1
0

Dac32.cpp 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667
  1. // ----------------------------------------------
  2. // - DAC32.DLL Implementations Datei -
  3. // - Written 1996-1998 by Christoph Schmelnik -
  4. // ----------------------------------------------
  5. // Version 1.33 : 18.01.1998
  6. // Changes:
  7. // Added speed selection support for all current Plextor drives
  8. //
  9. // Version 1.40 : 24.02.1998
  10. // Changes:
  11. // Set correct direction flags, to work with NT device IO interface and ATAPI drives
  12. // Changed main CD detection to TestUnitReady
  13. // Removed CD detection from Audio Status Info
  14. // Added hopefully correct read command for Matsushita/Panasonic drives
  15. // Added Parameters to CDAC class to allow the disabling of the audio test and to spin up the drive for a specified time
  16. // in seconds to avoid spin up problems on some drives. Both parameters have default values so it behaves like the old version
  17. // without the additional parameters
  18. // Added Parameter to the constructor of CWaveSave to disable writing any Headers. Also this parameter has a default to work like
  19. // before.
  20. // Added virtual function in CDAC to report buffer underruns in Burst Copy Mode
  21. // For the last feature an immediate parameter in WaitCDDA is added
  22. // GetLastSense function added to return the sense information for the last read audio command
  23. // Configuration in CMapDrive extended by new features
  24. // Added function to CD Class to read Media Cataloge Number
  25. //
  26. // Version 1.41 : 02.05.1998
  27. // Changes:
  28. // New GetInfoEx() function in CMapDrive, to allow a better result checking.
  29. // Bugfixed error handling in CWaveSave and CDAC regarding write errors
  30. //
  31. // Version 1.42 : 02.08.1998
  32. // Changes:
  33. // Added GetLastReadableAddress function to get the last readable Sektor of a session.
  34. // Added a flag in the drive properties for the function.
  35. // Added this function to the CDAC object.
  36. //
  37. // Version 1.43 : 23.12.1998
  38. // Changes:
  39. // Added Wave and DAC classes are now available in a MT version, the old versions will not longer be updated.
  40. //
  41. // Version 1.44 : 10.03.1999
  42. // Changes:
  43. // Added Support for current Plextor CDROM drives and CD-Writers.
  44. // Added Support for Jukeboxes
  45. // Changed Handling of the Ringbuffer
  46. //
  47. // Version 1.45 : 15.08.1999
  48. // Changes:
  49. // Added Enhanced error detection for Plextor drives.
  50. // Several Bugfixes (initialising under NT and Ringbuffer specific)
  51. //
  52. // Version 1.45-Build 11 : 11.11.1999
  53. // Changes:
  54. // Added a check for the MaxSektor parameter in CBaseWaveMT to avoid Program failures even if the applications provides an invalid value.
  55. // Changed source to comile with Borland compiler
  56. // Added MMC-2 Type which will be default for Sony CD-Writers 140 and 928
  57. // Skip Virtual CD devices in Bus scan
  58. // Fixed Array out of bound bug in drive detection.
  59. //limit the read to 64k, because of a bug in the Adaptec drivers
  60. #define Bug64
  61. //limit the number of retries at error to 5
  62. #define MAXTRIES 5
  63. #include "dac32.h"
  64. #include <stdlib.h>
  65. #include <assert.h>
  66. #include <process.h>
  67. #ifdef __BORLANDC__ // pgo (to make it compatible with Bormand compiler)
  68. #define _stricmp _stricmp
  69. #define _strlwr strlwr
  70. #endif
  71. // ----------------------------------------------------------------------------------------
  72. // - Implementation of the private copy operators -
  73. // - -
  74. // - Author: Christoph Schmelnik -
  75. // - Purpose: Check the syntax of program -
  76. // ----------------------------------------------------------------------------------------
  77. CBaseCD& CBaseCD::operator = (const CBaseCD &other)
  78. {
  79. assert(!&other);
  80. return (*this);
  81. }
  82. CSCSICD& CSCSICD::operator = (const CSCSICD &other)
  83. {
  84. assert(!&other);
  85. return (*this);
  86. }
  87. // ----------------------------------------------------------------------------------------
  88. // - Implementation of the class members of CCDAdress -
  89. // - -
  90. // - Author: Christoph Schmelnik -
  91. // - Purpose: Eliminate the errors at compile time -
  92. // ----------------------------------------------------------------------------------------
  93. void CCDAdress::SetRedbook(long Value)
  94. {
  95. Adresse=Value >> 24;
  96. Adresse+=((Value >> 16) & 255)*75;
  97. Adresse+=((Value >> 8) & 255)*4500;
  98. };
  99. // ----------------------------------------------------------------------------------------
  100. // - Implementation of the class members of CMapInfo -
  101. // - -
  102. // - Author: Christoph Schmelnik -
  103. // - Purpose: Implement the information of the TypeMappings -
  104. // ----------------------------------------------------------------------------------------
  105. CMapInfo::CMapInfo()
  106. {
  107. strncpy(TypNamen[0],"TOSHIBA ", 9);
  108. strncpy(TypNamen[1],"SONY ", 9);
  109. strncpy(TypNamen[2],"NEC ", 9);
  110. strncpy(TypNamen[3],"HITACHI ", 9);
  111. strncpy(TypNamen[4],"YAMAHA ", 9);
  112. strncpy(TypNamen[5],"PIONEER ", 9);
  113. strncpy(TypNamen[6],"IBM ", 9);
  114. strncpy(TypNamen[7],"PLEXTOR ", 9);
  115. strncpy(TypNamen[8],"PHILIPS ", 9);
  116. strncpy(TypNamen[9],"GRUNDIG ", 9);
  117. strncpy(TypNamen[10],"HP ", 9);
  118. strncpy(TypNamen[11],"IMS ", 9);
  119. strncpy(TypNamen[12],"MITSUMI ", 9);
  120. strncpy(TypNamen[13],"ATAPI ", 9);
  121. strncpy(TypNamen[14],"TOSHNEW ", 9);
  122. strncpy(TypNamen[15],"RICOH ", 9);
  123. strncpy(TypNamen[16],"MATSHITA", 9);
  124. strncpy(TypNamen[17],"PLASMON ", 9);
  125. strncpy(TypNamen[18],"KODAK ", 9);
  126. strncpy(TypNamen[19],"TEAC ", 9);
  127. strncpy(TypNamen[20],"CyberDrv", 9);
  128. strncpy(TypNamen[21],"MMC-2 ", 9); // pgo
  129. int const t[]={CDTYPE_TOSHIBA,CDTYPE_SONY,CDTYPE_NEC,CDTYPE_SONY,CDTYPE_SONY,CDTYPE_SONY,
  130. CDTYPE_SONY,CDTYPE_PLEXTOR,CDTYPE_PHILIPS,CDTYPE_PHILIPS,CDTYPE_PHILIPS,CDTYPE_PHILIPS,
  131. CDTYPE_PHILIPS,CDTYPE_ATAPI,CDTYPE_TOSHNEW,CDTYPE_RICOH,CDTYPE_MATSHITA,CDTYPE_PHILIPS,
  132. CDTYPE_PHILIPS,CDTYPE_SONY,CDTYPE_CYBERDRV,
  133. CDTYPE_CYBERDRV}; // pgo
  134. for (int i=0; i<MaxMappings; i++)
  135. TypMapping[i]=t[i];
  136. }
  137. char *CMapInfo::GetTypName(int Index)
  138. {
  139. return TypNamen[Index];
  140. };
  141. int CMapInfo::GetTypMapping(int Index)
  142. {
  143. return TypMapping[Index];
  144. };
  145. int CMapInfo::GetTypMappingRev(int CDType)
  146. {
  147. int Index=0;
  148. while ((Index<MaxMappings) &&
  149. (TypMapping[Index]!=CDType))
  150. Index++;
  151. return Index;
  152. };
  153. // ----------------------------------------------------------------------------------------
  154. // - Implementation of the class members of CMapDrive -
  155. // - -
  156. // - Author: Christoph Schmelnik -
  157. // - Purpose: Administration of the drive configuration -
  158. // ----------------------------------------------------------------------------------------
  159. CMapDrive::CMapDrive(BOOL bDoReset)
  160. {
  161. First=0;
  162. m_hDriveEvent=INVALID_HANDLE_VALUE;
  163. wchar_t szEventName[32] = {0};
  164. wsprintf(szEventName,L"%X",this);
  165. m_hDriveEvent=CreateEvent(NULL,TRUE,FALSE,szEventName);
  166. if (bDoReset)
  167. Reset();
  168. };
  169. CMapDrive::~CMapDrive()
  170. {
  171. DeleteAll();
  172. if (m_hDriveEvent!=INVALID_HANDLE_VALUE)
  173. CloseHandle(m_hDriveEvent);
  174. };
  175. void CMapDrive::DeleteAll()
  176. {
  177. TDriveInfoMem *Akt;
  178. Akt=First;
  179. while (First)
  180. {
  181. Akt=First;
  182. First=Akt->Next;
  183. delete Akt;
  184. }
  185. };
  186. void CMapDrive::Reset()
  187. {
  188. TDriveInfoMem *Akt,*Last;
  189. DeleteAll();
  190. BYTE SCSIType;
  191. TDriveInfo Info = {0};
  192. int DType = DTYPE_UNKNOWN;
  193. char Revision[5] = {0};
  194. char ManagerID[17] = {0};
  195. char HAID[17] = {0};
  196. THAUnique HAUnique;
  197. MEMORYSTATUS MemStat;
  198. MemStat.dwLength=sizeof(MEMORYSTATUS);
  199. GlobalMemoryStatus((LPMEMORYSTATUS)&MemStat);
  200. CMapInfo MapInfo;
  201. int HostNum;
  202. for (HostNum=0; HostNum<NumberOfHostAdapters; HostNum++)
  203. {
  204. memset(Revision,0,sizeof(Revision));
  205. memset(ManagerID,0,sizeof(ManagerID));
  206. memset(HAID,0,sizeof(HAID));
  207. memset(&HAUnique,0,sizeof(HAUnique));
  208. if (HAInquiry(HostNum,ManagerID,HAID,HAUnique))
  209. {
  210. if (_stricmp(HAID, "fastcdmp") == 0) //pgo: Skip Virtual CD Adapter in Bus Scan
  211. continue;
  212. HostAdapterMemory[HostNum]=HAUnique.MaximumTransferLen;
  213. for (int IDNum=0; IDNum<8; IDNum++)
  214. for (int LUNNum=0; LUNNum<=MAXLUN; LUNNum++)
  215. {
  216. DType=GetDeviceInfo(HostNum,IDNum,LUNNum,SCSIType,Info.VendorID,Info.ProductID,Revision,m_hDriveEvent);
  217. if ((DType==DTYPE_CROM)||
  218. (DType==DTYPE_WORM))
  219. {
  220. if (SCSIType)
  221. {
  222. int i;
  223. for (i=0; (i<MaxMappings) && _stricmp(Info.VendorID,MapInfo.GetTypName(i)); i++);
  224. if (i>=MaxMappings) i=1; //pgo: avoid array out of bound
  225. Info.Type=i;
  226. }
  227. else
  228. Info.Type=MapInfo.GetTypMappingRev(CDTYPE_ATAPI);
  229. if (MapInfo.GetTypMapping(Info.Type)==CDTYPE_TOSHIBA)
  230. {
  231. char szNumbers[17] = {0};
  232. for (size_t i=0; i<strlen(Info.ProductID); i++)
  233. if (isdigit(Info.ProductID[i]))
  234. strncat(szNumbers,&Info.ProductID[i],1);
  235. int nProductID=atoi(szNumbers);
  236. if (((nProductID>3800) &&
  237. (nProductID<4000)) ||
  238. ((nProductID>5700) &&
  239. (nProductID<10000)))
  240. Info.Type=MapInfo.GetTypMappingRev(CDTYPE_TOSHNEW);
  241. }
  242. // pgo
  243. else if (MapInfo.GetTypMapping(Info.Type)==CDTYPE_SONY)
  244. {
  245. if (SCSIType)
  246. {
  247. char szNumbers[17] = {0};
  248. for (size_t i=0; i<strlen(Info.ProductID); i++)
  249. if (isdigit(Info.ProductID[i]))
  250. strncat(szNumbers,&Info.ProductID[i],1);
  251. int nProductID=atoi(szNumbers);
  252. if ((nProductID == 140) || (nProductID == 928))
  253. Info.Type=MapInfo.GetTypMappingRev(CDTYPE_CYBERDRV);
  254. }
  255. }
  256. Info.ID=IDNum;
  257. Info.LUN=LUNNum;
  258. Info.HostAdapterNumber=HostNum;
  259. Info.Mode=ModeBurst;
  260. Info.MaxSektors=MemStat.dwTotalPhys/16/2352;
  261. if (Info.MaxSektors>(HostAdapterMemory[HostNum]/2352))
  262. Info.MaxSektors=HostAdapterMemory[HostNum]/2352;
  263. #ifdef Bug64
  264. if (Info.MaxSektors>27) Info.MaxSektors=27;
  265. #else
  266. if (Info.MaxSektors>446) Info.MaxSektors=446;
  267. #endif
  268. if (!Info.MaxSektors) Info.MaxSektors=26;
  269. Info.SynchSektors=3;
  270. Info.Speed=0;
  271. Info.PerformDATest=DATEST_FIRSTTRACK;
  272. Info.SpinUpMode=SPINUP_NEVER;
  273. Info.dwSpinUpTime=5;
  274. Info.bUseLastReadableAddress=FALSE;
  275. Info.bUseC2ErrorInfo=FALSE;
  276. Info.bSpinDown=FALSE;
  277. Akt=new TDriveInfoMem;
  278. Akt->Info=Info;
  279. Akt->Next=0;
  280. if (!First) First=Akt;
  281. else Last->Next=Akt;
  282. //Last must be set to Akt
  283. Last=Akt;
  284. }
  285. }
  286. }
  287. }
  288. if (RunningNT)
  289. {
  290. //check all drives for direct access
  291. int Index, Length;
  292. wchar_t DriveList[128] = {0}, *pDrives = 0;
  293. Length=GetLogicalDriveStrings(128,DriveList);
  294. if (Length)
  295. {
  296. pDrives=DriveList;
  297. Index=0;
  298. while (pDrives && *pDrives && (Index<Length))
  299. {
  300. if (GetDriveType(pDrives)==DRIVE_CDROM)
  301. {
  302. wchar_t CDDevice[10]=L"\\\\.\\x:";
  303. HANDLE hDrive;
  304. CharLower(pDrives);
  305. //_strlwr(pDrives);
  306. CDDevice[4]=pDrives[0];
  307. int IDNum=pDrives[0]-'a';
  308. //For Windows NT 5 use other file flags
  309. OSVERSIONINFO osver;
  310. memset( &osver, 0x00, sizeof(osver) );
  311. osver.dwOSVersionInfoSize = sizeof(osver);
  312. GetVersionEx( &osver );
  313. DWORD dwOpenFlags = GENERIC_READ;
  314. if ( (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osver.dwMajorVersion > 4) ) dwOpenFlags |= GENERIC_WRITE;
  315. hDrive=CreateFile(CDDevice,dwOpenFlags,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
  316. if (hDrive!=INVALID_HANDLE_VALUE)
  317. {
  318. //CT> added correct host/id/lun guessing
  319. extern int getSCSIIDFromDrive(char driveletter, int *host, int *id, int *lun);
  320. int m_lun;
  321. getSCSIIDFromDrive((char)pDrives[0],&HostNum,&IDNum,&m_lun);
  322. DType=GetDeviceInfo(HostNum,IDNum,m_lun,SCSIType,Info.VendorID,Info.ProductID,Revision,hDrive);
  323. if ((DType==DTYPE_CROM)||
  324. (DType==DTYPE_WORM))
  325. {
  326. SCSIMaxBlocks(hDrive,&HostAdapterMemory[HostNum]);
  327. if (SCSIType)
  328. {
  329. int i;
  330. for (i=0; (i<MaxMappings) && _stricmp(Info.VendorID,MapInfo.GetTypName(i)); i++);
  331. if (i>=MaxMappings) i=1; //pgo: avoid array out of bound
  332. Info.Type=i;
  333. }
  334. else
  335. Info.Type=MapInfo.GetTypMappingRev(CDTYPE_ATAPI);
  336. if (MapInfo.GetTypMapping(Info.Type)==CDTYPE_TOSHIBA)
  337. {
  338. char szNumbers[17];
  339. szNumbers[0]=0;
  340. for (size_t i=0; i<strlen(Info.ProductID); i++)
  341. if (isdigit(Info.ProductID[i]))
  342. strncat(szNumbers,&Info.ProductID[i],1);
  343. int nProductID=atoi(szNumbers);
  344. if (((nProductID>3800) &&
  345. (nProductID<4000)) ||
  346. ((nProductID>5700) &&
  347. (nProductID<10000)))
  348. Info.Type=MapInfo.GetTypMappingRev(CDTYPE_TOSHNEW);
  349. }
  350. // pgo
  351. else if (MapInfo.GetTypMapping(Info.Type)==CDTYPE_SONY)
  352. {
  353. if (SCSIType)
  354. {
  355. char szNumbers[17] = {0};
  356. for (size_t i=0; i<strlen(Info.ProductID); i++)
  357. if (isdigit(Info.ProductID[i]))
  358. strncat(szNumbers,&Info.ProductID[i],1);
  359. int nProductID=atoi(szNumbers);
  360. if ((nProductID == 140) || (nProductID == 928))
  361. Info.Type=MapInfo.GetTypMappingRev(CDTYPE_CYBERDRV);
  362. }
  363. }
  364. Info.ID=IDNum;
  365. Info.LUN=0;
  366. Info.HostAdapterNumber=HostNum;
  367. Info.Mode=ModeNormal;
  368. Info.MaxSektors=MemStat.dwTotalPhys/16/2352;
  369. if (Info.MaxSektors>(HostAdapterMemory[HostNum]/2352))
  370. Info.MaxSektors=HostAdapterMemory[HostNum]/2352;
  371. #ifdef Bug64
  372. if (Info.MaxSektors>27) Info.MaxSektors=27;
  373. #else
  374. if (Info.MaxSektors>446) Info.MaxSektors=446;
  375. #endif
  376. if (!Info.MaxSektors ||
  377. (MapInfo.GetTypMapping(Info.Type)==CDTYPE_ATAPI))
  378. Info.MaxSektors=26;
  379. Info.SynchSektors=3;
  380. Info.Speed=0;
  381. Info.PerformDATest=DATEST_FIRSTTRACK;
  382. Info.SpinUpMode=SPINUP_NEVER;
  383. Info.dwSpinUpTime=5;
  384. Info.bUseLastReadableAddress=FALSE;
  385. Info.bUseC2ErrorInfo=FALSE;
  386. Info.bSpinDown=FALSE;
  387. Akt=new TDriveInfoMem;
  388. Akt->Info=Info;
  389. Akt->Next=0;
  390. if (!First) First=Akt;
  391. else Last->Next=Akt;
  392. //Last must be set to Akt
  393. Last=Akt;
  394. HostNum++;
  395. }
  396. CloseHandle(hDrive);
  397. }
  398. }
  399. pDrives+=4;
  400. Index+=4;
  401. }
  402. }
  403. }
  404. };
  405. int CMapDrive::GetMaxDrives()
  406. {
  407. int i=0;
  408. TDriveInfoMem *Akt;
  409. Akt=First;
  410. while (Akt)
  411. {
  412. i++;
  413. Akt=Akt->Next;
  414. }
  415. return i;
  416. };
  417. TDriveInfo &CMapDrive::GetInfo(int index)
  418. {
  419. int i=0;
  420. TDriveInfoMem *Akt;
  421. Akt=First;
  422. while ((Akt) && (i<index))
  423. {
  424. i++;
  425. Akt=Akt->Next;
  426. }
  427. return Akt->Info;
  428. };
  429. BOOL CMapDrive::GetInfoEx(int index, TDriveInfo *&pInfo)
  430. {
  431. int i=0;
  432. TDriveInfoMem *Akt;
  433. Akt=First;
  434. while ((Akt) && (i<index))
  435. {
  436. i++;
  437. Akt=Akt->Next;
  438. }
  439. if (!Akt)
  440. return FALSE;
  441. pInfo=&Akt->Info;
  442. return TRUE;
  443. };
  444. void CMapDrive::DeleteInfo(int index)
  445. {
  446. int i=0;
  447. TDriveInfoMem *Akt,*Prev;
  448. Akt=First;
  449. Prev=0;
  450. while ((Akt) && (i<index))
  451. {
  452. i++;
  453. Prev=Akt;
  454. Akt=Akt->Next;
  455. }
  456. if (!Akt) return;
  457. if (Prev) Prev->Next=Akt->Next;
  458. else First=Akt->Next;
  459. delete Akt;
  460. };
  461. int CMapDrive::GetMaxHostAdapters()
  462. {
  463. return NumberOfHostAdapters;
  464. };
  465. int CMapDrive::GetSupportedHostAdapterMemory(int index)
  466. {
  467. if ((index<NumberOfHostAdapters) &&
  468. (index>=0))
  469. return HostAdapterMemory[index];
  470. else
  471. return -1;
  472. };
  473. void CMapDrive::SetSupportedHostAdapterMemory(int index,int Memory)
  474. {
  475. if ((index<NumberOfHostAdapters) &&
  476. (index>=0))
  477. HostAdapterMemory[index]=Memory;
  478. }
  479. int CMapDrive::GetMaxSektors(int HostAdapterNumber)
  480. {
  481. #ifdef Bug64
  482. int Result=HostAdapterMemory[HostAdapterNumber]/2352;
  483. if (Result>27)
  484. Result=27;
  485. return Result;
  486. #else
  487. return HostAdapterMemory[HostAdapterNumber]/2352;
  488. #endif
  489. };
  490. // ----------------------------------------------------------------------------------------
  491. // - Implementation of the class members of CMapInfoJuke -
  492. // - -
  493. // - Author: Christoph Schmelnik -
  494. // - Purpose: Implement the information of the TypeMappings -
  495. // ----------------------------------------------------------------------------------------
  496. CMapInfoJuke::CMapInfoJuke()
  497. {
  498. strncpy(TypNamen[0],"SONY ", 9);
  499. strncpy(TypNamen[1],"PIONEER ", 9);
  500. int const t[]={JUKETYPE_SONY,JUKETYPE_PIONEER};
  501. for (int i=0; i<MaxMappingsJuke; i++)
  502. TypMapping[i]=t[i];
  503. }
  504. char *CMapInfoJuke::GetTypName(int Index)
  505. {
  506. return TypNamen[Index];
  507. };
  508. int CMapInfoJuke::GetTypMapping(int Index)
  509. {
  510. return TypMapping[Index];
  511. };
  512. int CMapInfoJuke::GetTypMappingRev(int JukeType)
  513. {
  514. int Index=0;
  515. while ((Index<MaxMappingsJuke) &&
  516. (TypMapping[Index]!=JukeType))
  517. Index++;
  518. return Index;
  519. };
  520. // ----------------------------------------------------------------------------------------
  521. // - Implementation of the class members of CMapJuke -
  522. // - -
  523. // - Author: Christoph Schmelnik -
  524. // - Purpose: Administration of the jukebox configuration -
  525. // ----------------------------------------------------------------------------------------
  526. CMapJuke::CMapJuke(BOOL bDoReset)
  527. {
  528. First=0;
  529. m_hJukeEvent=INVALID_HANDLE_VALUE;
  530. wchar_t szEventName[32] = {0};
  531. wsprintf(szEventName,L"%X",this);
  532. m_hJukeEvent=CreateEvent(NULL,TRUE,FALSE,szEventName);
  533. if (bDoReset)
  534. Reset();
  535. };
  536. CMapJuke::~CMapJuke()
  537. {
  538. DeleteAll();
  539. if (m_hJukeEvent!=INVALID_HANDLE_VALUE)
  540. CloseHandle(m_hJukeEvent);
  541. };
  542. void CMapJuke::DeleteAll()
  543. {
  544. TJukeInfoMem *Akt;
  545. Akt=First;
  546. while (First)
  547. {
  548. Akt=First;
  549. First=Akt->Next;
  550. if (Akt->Info.pConnectedDrives)
  551. delete Akt->Info.pConnectedDrives;
  552. delete Akt;
  553. }
  554. };
  555. void CMapJuke::Reset()
  556. {
  557. TJukeInfoMem *Akt,*Last;
  558. DeleteAll();
  559. BYTE SCSIType = 0;
  560. TJukeInfo Info = {0};
  561. int DType = DTYPE_UNKNOWN;
  562. char Revision[5] = {0};
  563. char ManagerID[17] = {0};
  564. char HAID[17] = {0};
  565. THAUnique HAUnique;
  566. CMapInfoJuke MapInfo;
  567. for (int HostNum=0; HostNum<NumberOfHostAdapters; HostNum++)
  568. {
  569. memset(Revision,0,sizeof(Revision));
  570. memset(ManagerID,0,sizeof(ManagerID));
  571. memset(HAID,0,sizeof(HAID));
  572. memset(&HAUnique,0,sizeof(HAUnique));
  573. if (HAInquiry(HostNum,ManagerID,HAID,HAUnique))
  574. {
  575. for (int IDNum=0; IDNum<8; IDNum++)
  576. {
  577. for (int LUNNum=0; LUNNum<=MAXLUN; LUNNum++)
  578. {
  579. memset(&Info,0,sizeof(Info));
  580. DType=GetDeviceInfo(HostNum,IDNum,LUNNum,SCSIType,Info.VendorID,Info.ProductID,Revision,m_hJukeEvent);
  581. if (DType==DTYPE_JUKE)
  582. {
  583. int i;
  584. for (i=0; (i<MaxMappingsJuke) && _stricmp(Info.VendorID,MapInfo.GetTypName(i)); i++);
  585. if (_stricmp(Info.VendorID,MapInfo.GetTypName(i))) i=JUKETYPE_SONY;
  586. Info.Type=i;
  587. switch (Info.Type)
  588. {
  589. case JUKETYPE_PIONEER :
  590. Info.MaxDrives=4; //currently only data for the 500x changer implemeneted
  591. Info.MaxDiscs=500;
  592. break;
  593. case JUKETYPE_SONY :
  594. default:
  595. Info.MaxDrives=2;
  596. Info.MaxDiscs=100;
  597. break;
  598. }
  599. Info.pConnectedDrives=new int[Info.MaxDrives];
  600. for (int nDriveNum=0; nDriveNum<Info.MaxDrives; nDriveNum++)
  601. Info.pConnectedDrives[nDriveNum]=-1;
  602. Info.ID=IDNum;
  603. Info.LUN=LUNNum;
  604. Info.HostAdapterNumber=HostNum;
  605. Akt=new TJukeInfoMem;
  606. Akt->Info=Info;
  607. Akt->bIsWorking=FALSE;
  608. Akt->Next=0;
  609. if (!First) First=Akt;
  610. else Last->Next=Akt;
  611. //Last must be set to Akt
  612. Last=Akt;
  613. }
  614. }
  615. }
  616. }
  617. }
  618. };
  619. int CMapJuke::GetMaxJukes()
  620. {
  621. int i=0;
  622. TJukeInfoMem *Akt;
  623. Akt=First;
  624. while (Akt)
  625. {
  626. i++;
  627. Akt=Akt->Next;
  628. }
  629. return i;
  630. };
  631. TJukeInfo &CMapJuke::GetInfo(int index)
  632. {
  633. int i=0;
  634. TJukeInfoMem *Akt;
  635. Akt=First;
  636. while ((Akt) && (i<index))
  637. {
  638. i++;
  639. Akt=Akt->Next;
  640. }
  641. return Akt->Info;
  642. };
  643. BOOL CMapJuke::IsWorking(int index)
  644. {
  645. int i=0;
  646. TJukeInfoMem *Akt;
  647. Akt=First;
  648. while ((Akt) && (i<index))
  649. {
  650. i++;
  651. Akt=Akt->Next;
  652. }
  653. return Akt->bIsWorking;
  654. };
  655. void CMapJuke::SetWorking(int index,BOOL bIsWorking)
  656. {
  657. int i=0;
  658. TJukeInfoMem *Akt;
  659. Akt=First;
  660. while ((Akt) && (i<index))
  661. {
  662. i++;
  663. Akt=Akt->Next;
  664. }
  665. Akt->bIsWorking=bIsWorking;
  666. };
  667. void CMapJuke::DeleteInfo(int index)
  668. {
  669. int i=0;
  670. TJukeInfoMem *Akt,*Prev;
  671. Akt=First;
  672. Prev=0;
  673. while ((Akt) && (i<index))
  674. {
  675. i++;
  676. Prev=Akt;
  677. Akt=Akt->Next;
  678. }
  679. if (!Akt) return;
  680. if (Prev) Prev->Next=Akt->Next;
  681. else First=Akt->Next;
  682. if (Akt->Info.pConnectedDrives)
  683. delete Akt->Info.pConnectedDrives;
  684. delete Akt;
  685. };
  686. // ----------------------------------------------------------------------------------------
  687. // - Implementation of the class members of CJukeBox -
  688. // - -
  689. // - Author: Christoph Schmelnik -
  690. // - Purpose: Control the basic JukeBox functions over ASPI -
  691. // ----------------------------------------------------------------------------------------
  692. CJukeBox::CJukeBox (TJukeInfo &xInfo):Config(xInfo)
  693. {
  694. m_hJukeEvent=INVALID_HANDLE_VALUE;
  695. wchar_t szEventName[32] = {0};
  696. wsprintf(szEventName,L"%X",this);
  697. m_hJukeEvent=CreateEvent(NULL,TRUE,FALSE,szEventName);
  698. assert(m_hJukeEvent);
  699. }
  700. CJukeBox::~CJukeBox()
  701. {
  702. if (m_hJukeEvent!=INVALID_HANDLE_VALUE)
  703. CloseHandle(m_hJukeEvent);
  704. }
  705. BOOL CJukeBox::MoveMedium(int Source,int Destination)
  706. {
  707. switch (MapInfo.GetTypMapping(Config.Type))
  708. {
  709. case JUKETYPE_PIONEER :
  710. if ((Source<1) || (Source>Config.MaxDiscs))
  711. if ((Source<0x4000) || (Source>=(0x4000+Config.MaxDrives)))
  712. return FALSE;
  713. if ((Destination<1) || (Destination>Config.MaxDiscs))
  714. if ((Destination<0x4000) || (Destination>=(0x4000+Config.MaxDrives)))
  715. return FALSE;
  716. break;
  717. case JUKETYPE_SONY :
  718. default:
  719. if ((Source<1) || (Source>Config.MaxDiscs))
  720. {
  721. if ((Source<0x4000) || (Source>=(0x4000+Config.MaxDrives)))
  722. return FALSE;
  723. else
  724. Source-=0x3fff;
  725. }
  726. else
  727. Source+=10;
  728. if ((Destination<1) || (Destination>Config.MaxDiscs))
  729. {
  730. if ((Destination<0x4000) || (Destination>=(0x4000+Config.MaxDrives)))
  731. return FALSE;
  732. else
  733. Destination-=0x3fff;
  734. }
  735. else
  736. Destination+=10;
  737. break;
  738. }
  739. while (!TestUnitReady(Config.HostAdapterNumber,Config.ID,Config.LUN,m_hJukeEvent));
  740. TOpcode OpC;
  741. OpC[0]=0xa5;
  742. OpC[1]=Config.LUN>>5;
  743. OpC[2]=0x00;
  744. OpC[3]=0x00;
  745. OpC[4]=Source/256;
  746. OpC[5]=Source%256;
  747. OpC[6]=Destination/256;
  748. OpC[7]=Destination%256;
  749. OpC[8]=0x00;
  750. OpC[9]=0x00;
  751. OpC[10]=0x00;
  752. OpC[11]=0x00;
  753. return ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,12,NULL,0,m_hJukeEvent);
  754. }
  755. // ----------------------------------------------------------------------------------------
  756. // - Implementation of the class members of CBaseCD -
  757. // - -
  758. // - Author: Christoph Schmelnik -
  759. // - Purpose: The drive independent functions to access the CD-ROM drives -
  760. // ----------------------------------------------------------------------------------------
  761. int CBaseCD::Lasterror()
  762. {
  763. int h;
  764. h=Error;
  765. Error=CDOK;
  766. return h;
  767. }
  768. int CBaseCD::ReadFirstTrackInfo(TTrackList &Infos)
  769. {
  770. if (!FirstTrack) return 0;
  771. AktTrack=FirstTrack;
  772. Infos=AktTrack->Info;
  773. return 1;
  774. }
  775. int CBaseCD::ReadNextTrackInfo(TTrackList &Infos)
  776. {
  777. if ((!FirstTrack) ||
  778. (!AktTrack->Next)) return 0;
  779. AktTrack=AktTrack->Next;
  780. Infos=AktTrack->Info;
  781. return 1;
  782. }
  783. int CBaseCD::ReadPrevTrackInfo(TTrackList &Infos)
  784. {
  785. if ((!FirstTrack) ||
  786. (!AktTrack->Prev)) return 0;
  787. AktTrack=AktTrack->Prev;
  788. Infos=AktTrack->Info;
  789. return 1;
  790. }
  791. int CBaseCD::ReadTrackInfo(TTrackList &Infos)
  792. {
  793. if ((!FirstTrack) ||
  794. (Infos.TrackNummer<1)) return 0;
  795. if (!AktTrack)
  796. AktTrack=FirstTrack;
  797. if (AktTrack->Info.TrackNummer==Infos.TrackNummer)
  798. {
  799. Infos=AktTrack->Info;
  800. return 1;
  801. }
  802. while ((AktTrack->Info.TrackNummer>Infos.TrackNummer) &&
  803. (AktTrack->Prev))
  804. AktTrack=AktTrack->Prev;
  805. while ((AktTrack->Info.TrackNummer<Infos.TrackNummer) &&
  806. (AktTrack->Next))
  807. AktTrack=AktTrack->Next;
  808. if (AktTrack->Info.TrackNummer!=Infos.TrackNummer) return 0;
  809. Infos=AktTrack->Info;
  810. return 1;
  811. }
  812. int CBaseCD::ReadMaxTracks()
  813. {
  814. TTrackListeMem *Laeufer;
  815. if (!FirstTrack) return 0;
  816. Laeufer=AktTrack;
  817. while (Laeufer->Next)
  818. Laeufer=Laeufer->Next;
  819. return Laeufer->Info.TrackNummer;
  820. }
  821. void CBaseCD::DeleteTrackList()
  822. {
  823. while (FirstTrack)
  824. {
  825. AktTrack=FirstTrack->Next;
  826. delete FirstTrack;
  827. FirstTrack=AktTrack;
  828. }
  829. }
  830. // ----------------------------------------------------------------------------------------
  831. // - Implementation of the class members of CSCSICD -
  832. // - -
  833. // - Author: Christoph Schmelnik -
  834. // - Purpose: Control the basic CDROM functions over ASPI -
  835. // ----------------------------------------------------------------------------------------
  836. CSCSICD::CSCSICD (char drive, TDriveInfo &xInfo):Config(xInfo)
  837. {
  838. m_bSpeedTableInitialized=FALSE;
  839. FirstTrack=0;
  840. NECRotationSpeed = 0; // pgo
  841. Changed=FALSE;
  842. CDPresentLast=TRUE;
  843. Error=CDOK;
  844. m_hDriveEvent=INVALID_HANDLE_VALUE;
  845. memset(&m_SenseInfo,0,sizeof(TSenseInfo));
  846. if ((Config.HostAdapterNumber>=NumberOfHostAdapters) &&
  847. RunningNT)
  848. {
  849. DWORD dwFlags;
  850. OSVERSIONINFO osver;
  851. wchar_t CDDevice[10]=L"\\\\.\\x:";
  852. CDDevice[4]=(wchar_t)drive;//(Config.HostAdapterNumber + 'A'/* + 1*/);
  853. //For Windows NT 5 use other file flags
  854. memset( &osver, 0x00, sizeof(osver) );
  855. osver.dwOSVersionInfoSize = sizeof(osver);
  856. GetVersionEx( &osver );
  857. // if Win2K or greater, add GENERIC_WRITE
  858. dwFlags = GENERIC_READ;
  859. if ( (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osver.dwMajorVersion > 4) ) dwFlags |= GENERIC_WRITE;
  860. m_hDriveEvent = CreateFile( CDDevice, dwFlags, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
  861. }
  862. else
  863. {
  864. wchar_t szEventName[32] = {0};
  865. wsprintf(szEventName,L"%X",this);
  866. m_hDriveEvent=CreateEvent(NULL,TRUE,FALSE,szEventName);
  867. assert(m_hDriveEvent);
  868. }
  869. TDriveStatus DInfo=Get_DriveStatus();
  870. if (DInfo.CDPresent) ReRead();
  871. }
  872. CSCSICD::~CSCSICD()
  873. {
  874. DeleteTrackList();
  875. if (m_hDriveEvent!=INVALID_HANDLE_VALUE)
  876. CloseHandle(m_hDriveEvent);
  877. }
  878. void CSCSICD::PrepareCDDA()
  879. {
  880. switch (MapInfo.GetTypMapping(Config.Type))
  881. {
  882. case CDTYPE_TOSHIBA :
  883. {
  884. memset(&ModeData,0,sizeof(ModeData));
  885. if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,0,m_hDriveEvent))
  886. {
  887. Error=CDASPIError;
  888. return;
  889. }
  890. ModeData[0]=0;
  891. TDriveMode ModeSelectData;
  892. ModeSelectData[0]=0x00;
  893. ModeSelectData[1]=0x00;
  894. ModeSelectData[2]=0x00;
  895. ModeSelectData[3]=0x08;
  896. ModeSelectData[4]=0x82;
  897. ModeSelectData[5]=0x00;
  898. ModeSelectData[6]=0x00;
  899. ModeSelectData[7]=0x00;
  900. ModeSelectData[8]=0x00;
  901. ModeSelectData[9]=0x00;
  902. ModeSelectData[10]=0x09;
  903. ModeSelectData[11]=0x30;
  904. if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSelectData,12,m_hDriveEvent))
  905. {
  906. Error=CDASPIError;
  907. return;
  908. }
  909. break;
  910. }
  911. case CDTYPE_TOSHNEW :
  912. {
  913. memset(&ModeData,0,sizeof(ModeData));
  914. if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,15,0x20,m_hDriveEvent))
  915. {
  916. Error=CDASPIError;
  917. return;
  918. }
  919. ModeData[0]=0;
  920. TDriveMode ModeSelectData;
  921. ModeSelectData[0]=0x00;
  922. ModeSelectData[1]=0x00;
  923. ModeSelectData[2]=0x00;
  924. ModeSelectData[3]=0x08;
  925. ModeSelectData[4]=0x82;
  926. ModeSelectData[5]=0x00;
  927. ModeSelectData[6]=0x00;
  928. ModeSelectData[7]=0x00;
  929. ModeSelectData[8]=0x00;
  930. ModeSelectData[9]=0x00;
  931. ModeSelectData[10]=0x09;
  932. ModeSelectData[11]=0x30;
  933. ModeSelectData[12]=0x20;
  934. ModeSelectData[13]=0x01;
  935. ModeSelectData[14]=(ModeData[14] & 0xcf)|0x10;
  936. if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSelectData,15,m_hDriveEvent))
  937. {
  938. Error=CDASPIError;
  939. return;
  940. }
  941. break;
  942. }
  943. case CDTYPE_NEC :
  944. {
  945. memset(&ModeData,0,sizeof(ModeData));
  946. if (!addModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,m_hDriveEvent))
  947. {
  948. Error=CDASPIError;
  949. return;
  950. }
  951. NECRotationSpeed=ModeData[6] & 0x20;
  952. ModeData[6]=ModeData[6]|0x20;
  953. if (!addModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,m_hDriveEvent))
  954. {
  955. Error=CDASPIError;
  956. return;
  957. }
  958. break;
  959. }
  960. case CDTYPE_PHILIPS :
  961. case CDTYPE_MATSHITA :
  962. {
  963. memset(&ModeData,0,sizeof(ModeData));
  964. if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,0,m_hDriveEvent))
  965. {
  966. Error=CDASPIError;
  967. return;
  968. }
  969. ModeData[0]=0;
  970. TDriveMode ModeSelectData;
  971. ModeSelectData[0]=0x00;
  972. ModeSelectData[1]=0x00;
  973. ModeSelectData[2]=0x00;
  974. ModeSelectData[3]=0x08;
  975. ModeSelectData[4]=0x00;
  976. ModeSelectData[5]=0x00;
  977. ModeSelectData[6]=0x00;
  978. ModeSelectData[7]=0x00;
  979. ModeSelectData[8]=0x00;
  980. ModeSelectData[9]=0x00;
  981. ModeSelectData[10]=0x09;
  982. ModeSelectData[11]=0x30;
  983. if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSelectData,12,m_hDriveEvent))
  984. {
  985. Error=CDASPIError;
  986. return;
  987. }
  988. break;
  989. }
  990. }
  991. }
  992. void CSCSICD::ReadCDDA(CCDAdress StartSektor,long Sektoranzahl,void *Buffer,BOOL bUseC2ErrorInfo)
  993. {
  994. TOpcode OpC;
  995. OpC[1]=0x00;
  996. OpC[2]=0x00;
  997. OpC[3]=LOBYTE(HIWORD(StartSektor.GetHSG()));
  998. OpC[4]=HIBYTE(LOWORD(StartSektor.GetHSG()));
  999. OpC[5]=LOBYTE(LOWORD(StartSektor.GetHSG()));
  1000. OpC[6]=0x00;
  1001. switch (MapInfo.GetTypMapping(Config.Type))
  1002. {
  1003. case CDTYPE_TOSHIBA :
  1004. case CDTYPE_TOSHNEW :
  1005. {
  1006. OpC[0]=0x28;
  1007. OpC[7]=HIBYTE(LOWORD(Sektoranzahl));
  1008. OpC[8]=LOBYTE(LOWORD(Sektoranzahl));
  1009. OpC[9]=0x00;
  1010. FillSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,Buffer,Sektoranzahl*2352,ReadSRB,m_hDriveEvent);
  1011. break;
  1012. }
  1013. case CDTYPE_SONY :
  1014. case CDTYPE_RICOH :
  1015. case CDTYPE_PLEXTOR :
  1016. {
  1017. OpC[0]=0xD8;
  1018. OpC[7]=0x00;
  1019. OpC[8]=HIBYTE(LOWORD(Sektoranzahl));
  1020. OpC[9]=LOBYTE(LOWORD(Sektoranzahl));
  1021. // benski
  1022. if (bUseC2ErrorInfo)
  1023. OpC[10]=0x04;
  1024. else
  1025. OpC[10]=0x00;
  1026. OpC[11]=0x00;
  1027. FillSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,12,Buffer,(bUseC2ErrorInfo)?(Sektoranzahl*2646):(Sektoranzahl*2352),ReadSRB,m_hDriveEvent);
  1028. break;
  1029. }
  1030. case CDTYPE_NEC :
  1031. {
  1032. OpC[0]=0xD4;
  1033. OpC[7]=HIBYTE(LOWORD(Sektoranzahl));
  1034. OpC[8]=LOBYTE(LOWORD(Sektoranzahl));
  1035. OpC[9]=0x00;
  1036. FillSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,Buffer,Sektoranzahl*2352,ReadSRB,m_hDriveEvent);
  1037. break;
  1038. }
  1039. case CDTYPE_MATSHITA :
  1040. {
  1041. OpC[0]=0xD4;
  1042. OpC[7]=0x00;
  1043. OpC[8]=HIBYTE(LOWORD(Sektoranzahl));
  1044. OpC[9]=LOBYTE(LOWORD(Sektoranzahl));
  1045. OpC[10]=0x00;
  1046. OpC[11]=0x00;
  1047. FillSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,12,Buffer,Sektoranzahl*2352,ReadSRB,m_hDriveEvent);
  1048. break;
  1049. }
  1050. case CDTYPE_PHILIPS :
  1051. {
  1052. OpC[0]=0x28;
  1053. OpC[7]=HIBYTE(LOWORD(Sektoranzahl));
  1054. OpC[8]=LOBYTE(LOWORD(Sektoranzahl));
  1055. OpC[9]=0x00;
  1056. FillSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,Buffer,Sektoranzahl*2352,ReadSRB,m_hDriveEvent);
  1057. break;
  1058. }
  1059. case CDTYPE_ATAPI :
  1060. case CDTYPE_CYBERDRV :
  1061. {
  1062. OpC[0]=0xBE;
  1063. OpC[1]=0x04;
  1064. OpC[7]=HIBYTE(LOWORD(Sektoranzahl));
  1065. OpC[8]=LOBYTE(LOWORD(Sektoranzahl));
  1066. OpC[9]=0xF0;
  1067. // benski
  1068. if (bUseC2ErrorInfo)
  1069. OpC[9]|=2; // flag 2 is supposed to mean check for C2 error info
  1070. OpC[10]=0x00;
  1071. OpC[11]=0x00;
  1072. // with C2 error info, our sector size is now 2646 bytes
  1073. FillSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,12,Buffer,bUseC2ErrorInfo?(Sektoranzahl*2646):(Sektoranzahl*2352),ReadSRB,m_hDriveEvent);
  1074. break;
  1075. }
  1076. }
  1077. ExecuteSCSIRequest(ReadSRB,m_hDriveEvent);
  1078. StartReadTime=GetTickCount();
  1079. }
  1080. BOOL CSCSICD::WaitCDDA(BOOL bImmediate)
  1081. {
  1082. BYTE Status=WaitSCSIRequest(ReadSRB,m_hDriveEvent,bImmediate);
  1083. if ((Status!=SS_PENDING) &&
  1084. (Status!=SS_COMP))
  1085. {
  1086. memcpy(&m_SenseInfo,&ReadSRB.SenseArea,SENSE_LEN);
  1087. Error=CDASPIError;
  1088. }
  1089. if ((Status==SS_PENDING) &&
  1090. !bImmediate)
  1091. {
  1092. DWORD AktReadTime=GetTickCount();
  1093. if (abs((long long)AktReadTime-StartReadTime)>12000)
  1094. {
  1095. AbortSCSIRequest(ReadSRB);
  1096. Error=CDTimeOut;
  1097. Status=SS_COMP;
  1098. }
  1099. }
  1100. return (Status!=SS_PENDING);
  1101. }
  1102. void CSCSICD::FinishCDDA()
  1103. {
  1104. switch (MapInfo.GetTypMapping(Config.Type))
  1105. {
  1106. case CDTYPE_TOSHIBA :
  1107. {
  1108. if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,m_hDriveEvent))
  1109. {
  1110. Error=CDASPIError;
  1111. return;
  1112. }
  1113. break;
  1114. }
  1115. case CDTYPE_TOSHNEW :
  1116. {
  1117. if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,15,m_hDriveEvent))
  1118. {
  1119. Error=CDASPIError;
  1120. return;
  1121. }
  1122. break;
  1123. }
  1124. case CDTYPE_NEC :
  1125. {
  1126. ModeData[6]=ModeData[6]|NECRotationSpeed;
  1127. if (!addModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,m_hDriveEvent))
  1128. {
  1129. Error=CDASPIError;
  1130. return;
  1131. }
  1132. break;
  1133. }
  1134. case CDTYPE_PHILIPS :
  1135. case CDTYPE_MATSHITA :
  1136. {
  1137. if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,m_hDriveEvent))
  1138. {
  1139. Error=CDASPIError;
  1140. return;
  1141. }
  1142. break;
  1143. }
  1144. }
  1145. }
  1146. void CSCSICD::SortWaveData(DWORD *Data,int Samples)
  1147. {
  1148. switch (MapInfo.GetTypMapping(Config.Type))
  1149. {
  1150. case CDTYPE_PHILIPS :
  1151. // RICOH Drives doesn't seem to swap the bytes
  1152. // This has been evaluated with the CD-RW drives
  1153. // So they are even just handled like SONY drives, but i don't remove this type
  1154. // case CDTYPE_RICOH :
  1155. {
  1156. for (int i=0; i<Samples; i++)
  1157. Data[i]=((Data[i]&0xff00ff00)>>8)|
  1158. ((Data[i]&0x00ff00ff)<<8);
  1159. break;
  1160. }
  1161. }
  1162. }
  1163. CCDAdress CSCSICD::GetErrorAdress()
  1164. {
  1165. CCDAdress h;
  1166. h.SetHSG(0);
  1167. if ((Error!=CDOK)&&
  1168. (ReadSRB.SRB_TargStat==STATUS_CHKCOND))
  1169. h.SetHSG((ReadSRB.SenseArea[3]<<24)+
  1170. (ReadSRB.SenseArea[4]<<16)+
  1171. (ReadSRB.SenseArea[5]<<8)+
  1172. ReadSRB.SenseArea[6]);
  1173. return h;
  1174. }
  1175. void CSCSICD::Play_Audio(CCDAdress StartSektor,long Sektoranzahl)
  1176. {
  1177. while (!TestUnitReady(Config.HostAdapterNumber,Config.ID,Config.LUN,m_hDriveEvent));
  1178. TOpcode OpC;
  1179. OpC[0]=0x45;
  1180. OpC[1]=0x00;
  1181. OpC[2]=HIBYTE(HIWORD(StartSektor.GetHSG()));
  1182. OpC[3]=LOBYTE(HIWORD(StartSektor.GetHSG()));
  1183. OpC[4]=HIBYTE(LOWORD(StartSektor.GetHSG()));
  1184. OpC[5]=LOBYTE(LOWORD(StartSektor.GetHSG()));
  1185. OpC[6]=0x00;
  1186. OpC[7]=HIBYTE(LOWORD(Sektoranzahl));
  1187. OpC[8]=LOBYTE(LOWORD(Sektoranzahl));
  1188. OpC[9]=0x00;
  1189. if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,10,NULL,0,m_hDriveEvent))
  1190. Error=CDDriveNotReady;
  1191. }
  1192. void CSCSICD::Stop_Audio()
  1193. {
  1194. while (!TestUnitReady(Config.HostAdapterNumber,Config.ID,Config.LUN,m_hDriveEvent));
  1195. TOpcode OpC;
  1196. /* OpC[0]=0x1b;
  1197. OpC[1]=0x00;
  1198. OpC[2]=0x00;
  1199. OpC[3]=0x00;
  1200. OpC[4]=0x00;
  1201. OpC[5]=0x00;
  1202. */
  1203. OpC[0]=0x2b;
  1204. OpC[1]=0x00;
  1205. OpC[2]=0x00;
  1206. OpC[3]=0x00;
  1207. OpC[4]=0x00;
  1208. OpC[5]=0x00;
  1209. OpC[6]=0x00;
  1210. OpC[7]=0x00;
  1211. OpC[8]=0x00;
  1212. OpC[9]=0x00;
  1213. if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,10,NULL,0,m_hDriveEvent))
  1214. Error=CDDriveNotReady;
  1215. }
  1216. void CSCSICD::Pause_Audio()
  1217. {
  1218. while (!TestUnitReady(Config.HostAdapterNumber,Config.ID,Config.LUN,m_hDriveEvent));
  1219. TOpcode OpC;
  1220. OpC[0]=0x4b;
  1221. OpC[1]=0x00;
  1222. OpC[2]=0x00;
  1223. OpC[3]=0x00;
  1224. OpC[4]=0x00;
  1225. OpC[5]=0x00;
  1226. OpC[6]=0x00;
  1227. OpC[7]=0x00;
  1228. OpC[8]=0x00;
  1229. OpC[9]=0x00;
  1230. if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,10,NULL,0,m_hDriveEvent))
  1231. Error=CDDriveNotReady;
  1232. }
  1233. void CSCSICD::Resume_Audio()
  1234. {
  1235. while (!TestUnitReady(Config.HostAdapterNumber,Config.ID,Config.LUN,m_hDriveEvent));
  1236. TOpcode OpC;
  1237. OpC[0]=0x4b;
  1238. OpC[1]=0x00;
  1239. OpC[2]=0x00;
  1240. OpC[3]=0x00;
  1241. OpC[4]=0x00;
  1242. OpC[5]=0x00;
  1243. OpC[6]=0x00;
  1244. OpC[7]=0x00;
  1245. OpC[8]=0x01;
  1246. OpC[9]=0x00;
  1247. if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,10,NULL,0,m_hDriveEvent))
  1248. Error=CDDriveNotReady;
  1249. }
  1250. TDriveStatus CSCSICD::Get_DriveStatus()
  1251. {
  1252. TDriveStatus h = {0};
  1253. /* TOpcode OpC;
  1254. TQChannelInfo ChannelInfo;
  1255. BOOL b;
  1256. memset(&ChannelInfo,0,sizeof(ChannelInfo));
  1257. OpC[0]=0x42;
  1258. OpC[1]=0x02;
  1259. OpC[2]=0x40;
  1260. OpC[3]=0x01;
  1261. OpC[4]=0x00;
  1262. OpC[5]=0x00;
  1263. OpC[6]=0x00;
  1264. OpC[7]=0x00;
  1265. OpC[8]=sizeof(ChannelInfo);
  1266. OpC[9]=0x00;
  1267. if (MapInfo.GetTypMapping(Config.Type)==CDTYPE_ATAPI)
  1268. {
  1269. OpC[10]=0;
  1270. OpC[11]=0;
  1271. b=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,12,(void *)&ChannelInfo,sizeof(ChannelInfo),m_hDriveEvent);
  1272. }
  1273. else
  1274. b=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,10,(void *)&ChannelInfo,sizeof(ChannelInfo),m_hDriveEvent);
  1275. if (b && ChannelInfo.DataLen)
  1276. */
  1277. if (TestUnitReady(Config.HostAdapterNumber,Config.ID,Config.LUN,m_hDriveEvent))
  1278. h.CDPresent=TRUE;
  1279. else
  1280. h.CDPresent=FALSE;
  1281. if (h.CDPresent!=CDPresentLast) Changed=TRUE;
  1282. CDPresentLast=h.CDPresent;
  1283. return h;
  1284. }
  1285. BOOL CSCSICD::MediaChanged()
  1286. {
  1287. BOOL h;
  1288. h=Changed;
  1289. //if (CDPresentLast)
  1290. Changed=FALSE;
  1291. return h;
  1292. }
  1293. TAudioStatus CSCSICD::Get_AudioStatus_Info()
  1294. {
  1295. TAudioStatus h;
  1296. TOpcode OpC;
  1297. TQChannelInfo ChannelInfo;
  1298. BOOL b;
  1299. memset(&ChannelInfo,0,sizeof(ChannelInfo));
  1300. OpC[0]=0x42;
  1301. OpC[1]=0x02;
  1302. OpC[2]=0x40;
  1303. OpC[3]=0x01;
  1304. OpC[4]=0x00;
  1305. OpC[5]=0x00;
  1306. OpC[6]=0x00;
  1307. OpC[7]=0x00;
  1308. OpC[8]=0x10;
  1309. OpC[9]=0x00;
  1310. h.Pause=FALSE;
  1311. h.IsPlaying=FALSE;
  1312. h.IsDone=FALSE;
  1313. h.PlayError=FALSE;
  1314. if (MapInfo.GetTypMapping(Config.Type)==CDTYPE_ATAPI)
  1315. {
  1316. OpC[10]=0;
  1317. OpC[11]=0;
  1318. b=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,12,(void *)&ChannelInfo,16,m_hDriveEvent);
  1319. }
  1320. else
  1321. b=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,(void *)&ChannelInfo,16,m_hDriveEvent);
  1322. if (b && ChannelInfo.DataLen)
  1323. {
  1324. // if (!CDPresentLast) Changed=TRUE;
  1325. // CDPresentLast=TRUE;
  1326. switch (ChannelInfo.AudioStatus)
  1327. {
  1328. case 0x11 : h.IsPlaying=TRUE; break;
  1329. case 0x12 : h.Pause=TRUE; break;
  1330. case 0x13 : h.IsDone=TRUE; break;
  1331. case 0x14 : h.PlayError=TRUE; break;
  1332. }
  1333. h.AbsSektor.SetRedbook(ChannelInfo.AbsCDAdress);
  1334. h.RelSektor.SetRedbook(ChannelInfo.RelTrackAdress);
  1335. h.TrackNummer=ChannelInfo.TrackNumber;
  1336. }
  1337. else
  1338. {
  1339. // if (CDPresentLast) Changed=TRUE;
  1340. // CDPresentLast=FALSE;
  1341. h.PlayError=TRUE;
  1342. Error=CDNoCD;
  1343. }
  1344. return h;
  1345. }
  1346. void CSCSICD::Get_MediaCatalogNumber(char szUPC[16])
  1347. {
  1348. TOpcode OpC;
  1349. BYTE Info[24] = {0};
  1350. BOOL b;
  1351. szUPC[0]=0;
  1352. OpC[0]=0x42;
  1353. OpC[1]=0x02;
  1354. OpC[2]=0x40;
  1355. OpC[3]=0x02;
  1356. OpC[4]=0x00;
  1357. OpC[5]=0x00;
  1358. OpC[6]=0x00;
  1359. OpC[7]=0x00;
  1360. OpC[8]=sizeof(Info);
  1361. OpC[9]=0x00;
  1362. if (MapInfo.GetTypMapping(Config.Type)==CDTYPE_ATAPI)
  1363. {
  1364. OpC[10]=0;
  1365. OpC[11]=0;
  1366. b=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,12,(void *)&Info,sizeof(Info),m_hDriveEvent);
  1367. }
  1368. else
  1369. b=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,(void *)&Info,sizeof(Info),m_hDriveEvent);
  1370. if (b && (Info[8]&0x80))
  1371. {
  1372. BOOL bIsEmpty=TRUE;
  1373. for (int i=0; i<15; i++)
  1374. {
  1375. BYTE Value=Info[i+9];
  1376. if (Value)
  1377. bIsEmpty=FALSE;
  1378. if (Value<10)
  1379. Value+=0x30;
  1380. szUPC[i]=Value;
  1381. }
  1382. szUPC[15]=0;
  1383. if (bIsEmpty)
  1384. szUPC[0]=0;
  1385. }
  1386. }
  1387. void CSCSICD::EjectDisk()
  1388. {
  1389. TOpcode OpC;
  1390. OpC[0]=0x1b;
  1391. OpC[1]=0x00;
  1392. OpC[2]=0x00;
  1393. OpC[3]=0x00;
  1394. OpC[4]=0x02;
  1395. OpC[5]=0x00;
  1396. if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,6,NULL,0,m_hDriveEvent))
  1397. Error=CDDriveNotReady;
  1398. }
  1399. void CSCSICD::LockDoor(int Lock)
  1400. {
  1401. TOpcode OpC;
  1402. OpC[0]=0x1e;
  1403. OpC[1]=0x00;
  1404. OpC[2]=0x00;
  1405. OpC[3]=0x00;
  1406. OpC[4]=((BYTE) Lock) & 1;
  1407. OpC[5]=0x00;
  1408. if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,6,NULL,0,m_hDriveEvent))
  1409. Error=CDDriveNotReady;
  1410. }
  1411. void CSCSICD::CloseTray()
  1412. {
  1413. TOpcode OpC;
  1414. OpC[0]=0x1b;
  1415. OpC[1]=0x00;
  1416. OpC[2]=0x00;
  1417. OpC[3]=0x00;
  1418. OpC[4]=0x03;
  1419. OpC[5]=0x00;
  1420. if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,6,NULL,0,m_hDriveEvent))
  1421. Error=CDDriveNotReady;
  1422. }
  1423. int Swap(int value)
  1424. {
  1425. int result=(value & 0xff000000)>>24;
  1426. result|=(value & 0x00ff0000)>>8;
  1427. result|=(value & 0x0000ff00)<<8;
  1428. result|=(value & 0x000000ff)<<24;
  1429. return result;
  1430. }
  1431. void CSCSICD::ReRead()
  1432. {
  1433. DeleteTrackList();
  1434. m_bSpeedTableInitialized=FALSE;
  1435. TTOCHeader TOCHeader;
  1436. memset(&TOCHeader,0,sizeof(TOCHeader));
  1437. TOpcode OpC;
  1438. OpC[0]=0x43;
  1439. OpC[1]=0;
  1440. OpC[2]=0;
  1441. OpC[3]=0;
  1442. OpC[4]=0;
  1443. OpC[5]=0;
  1444. OpC[6]=0;
  1445. OpC[7]=HIBYTE(sizeof(TTOCHeader));
  1446. OpC[8]=LOBYTE(sizeof(TTOCHeader));
  1447. OpC[9]=0;
  1448. BOOL r=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,(void*)&TOCHeader,sizeof(TOCHeader),m_hDriveEvent);
  1449. if (r && TOCHeader.FirstTrack && TOCHeader.LastTrack)
  1450. {
  1451. TTrackListeMem *Last;
  1452. CCDAdress Ende;
  1453. Last=FirstTrack;
  1454. for (int i=TOCHeader.FirstTrack; i<=TOCHeader.LastTrack; i++)
  1455. {
  1456. AktTrack=new TTrackListeMem;
  1457. //AbsCDAdress
  1458. //AdrCtrl
  1459. AktTrack->Info.TrackNummer=TOCHeader.Info[i-1].TrackNummer;
  1460. AktTrack->Info.StartSektor.SetHSG(Swap(TOCHeader.Info[i-1].AbsCDAdress)+150);
  1461. Ende.SetHSG(Swap(TOCHeader.Info[i].AbsCDAdress)+150);
  1462. AktTrack->Info.Laenge=Ende.GetHSG()-AktTrack->Info.StartSektor.GetHSG();
  1463. AktTrack->Info.StartSektor.SetHSG(AktTrack->Info.StartSektor.GetHSG()-150);
  1464. if (TOCHeader.Info[i-1].AdrCtrl & 8)
  1465. AktTrack->Info.Flags.AudioChannels=4;
  1466. else
  1467. AktTrack->Info.Flags.AudioChannels=2;
  1468. AktTrack->Info.Flags.PreEmphasis=(TOCHeader.Info[i-1].AdrCtrl & 1);
  1469. AktTrack->Info.Flags.DataTrack=(TOCHeader.Info[i-1].AdrCtrl & 4);
  1470. AktTrack->Info.Flags.CopyProhibeted=!(TOCHeader.Info[i-1].AdrCtrl & 2);
  1471. AktTrack->Prev=Last;
  1472. AktTrack->Next=0;
  1473. if (FirstTrack)
  1474. Last->Next=AktTrack;
  1475. else
  1476. FirstTrack=AktTrack;
  1477. Last=AktTrack;
  1478. }
  1479. // check for CD-Extra
  1480. if (AktTrack)
  1481. {
  1482. if (AktTrack->Info.Flags.DataTrack)
  1483. {
  1484. Last=AktTrack->Prev;
  1485. if (Last && !Last->Info.Flags.DataTrack)
  1486. {
  1487. if (Last->Info.Laenge>11400)
  1488. Last->Info.Laenge-=11400;
  1489. }
  1490. }
  1491. }
  1492. }
  1493. else
  1494. {
  1495. if (CDPresentLast) Changed=TRUE;
  1496. CDPresentLast=FALSE;
  1497. Error=CDDriveNotReady;
  1498. }
  1499. }
  1500. CCDAdress CSCSICD::GetLastReadableAddress(CCDAdress StartSektor)
  1501. {
  1502. CCDAdress LastSektor;
  1503. BYTE RetVal[8] = {0};
  1504. TOpcode OpC;
  1505. OpC[0]=0x25;
  1506. OpC[1]=0;
  1507. OpC[2]=HIBYTE(HIWORD(StartSektor.GetHSG()));
  1508. OpC[3]=LOBYTE(HIWORD(StartSektor.GetHSG()));
  1509. OpC[4]=HIBYTE(LOWORD(StartSektor.GetHSG()));
  1510. OpC[5]=LOBYTE(LOWORD(StartSektor.GetHSG()));
  1511. OpC[6]=0;
  1512. OpC[7]=0;
  1513. OpC[8]=1; //Set PMI Bit
  1514. OpC[9]=0;
  1515. BOOL r=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,(void*)&RetVal,sizeof(RetVal),m_hDriveEvent);
  1516. if (!r)
  1517. return StartSektor;
  1518. LastSektor.SetHSG((RetVal[0]<<24)+(RetVal[1]<<16)+(RetVal[2]<<8)+RetVal[3]);
  1519. return LastSektor;
  1520. }
  1521. int CSCSICD::GetMaxSektors()
  1522. {
  1523. return Config.MaxSektors;
  1524. };
  1525. int CSCSICD::GetSynchSektors()
  1526. {
  1527. return Config.SynchSektors;
  1528. };
  1529. int CSCSICD::GetMode()
  1530. {
  1531. return Config.Mode;
  1532. };
  1533. int CSCSICD::GetSpeed()
  1534. {
  1535. return Config.Speed;
  1536. };
  1537. TSenseInfo CSCSICD::GetSense()
  1538. {
  1539. TSenseInfo SenseInfo;
  1540. memset(&SenseInfo,0,sizeof(SenseInfo));
  1541. TOpcode OpC;
  1542. OpC[0]=0x03;
  1543. OpC[1]=0;
  1544. OpC[2]=0;
  1545. OpC[3]=0;
  1546. OpC[4]=sizeof(SenseInfo);
  1547. OpC[5]=0;
  1548. BOOL r=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,6,(void*)&SenseInfo,sizeof(SenseInfo),m_hDriveEvent);
  1549. if (!r)
  1550. memset(&SenseInfo,0,sizeof(SenseInfo));
  1551. return SenseInfo;
  1552. }
  1553. TSenseInfo CSCSICD::GetLastSenseInfo()
  1554. {
  1555. TSenseInfo Info=m_SenseInfo;
  1556. memset(&m_SenseInfo,0,sizeof(TSenseInfo));
  1557. return Info;
  1558. }
  1559. void CSCSICD::InitSpeedTable()
  1560. {
  1561. if (m_bSpeedTableInitialized)
  1562. return;
  1563. SupportedSpeeds=0;
  1564. switch (MapInfo.GetTypMapping(Config.Type))
  1565. {
  1566. case CDTYPE_TOSHIBA :
  1567. break;
  1568. case CDTYPE_TOSHNEW :
  1569. {
  1570. SpeedTable[0]=2352*75;
  1571. SpeedTable[1]=2352*75*4;
  1572. SpeedTable[2]=2352*75*4;
  1573. SpeedTable[3]=-2;
  1574. SupportedSpeeds=4;
  1575. break;
  1576. }
  1577. case CDTYPE_SONY :
  1578. case CDTYPE_RICOH :
  1579. case CDTYPE_ATAPI :
  1580. case CDTYPE_CYBERDRV :
  1581. {
  1582. int LastSpeed=GetCurrentSpeed();
  1583. int Speed=65532000;
  1584. BOOL bFound=FALSE;
  1585. while (!bFound && (Speed>0))
  1586. {
  1587. SetCurrentSpeed(Speed);
  1588. if (Lasterror()==CDOK)
  1589. {
  1590. int ResultingSpeed=GetCurrentSpeed();
  1591. if (Lasterror()==CDOK)
  1592. {
  1593. bFound=FALSE;
  1594. for (int i=0; i<SupportedSpeeds; i++)
  1595. {
  1596. if (SpeedTable[i]==ResultingSpeed)
  1597. bFound=TRUE;
  1598. }
  1599. if (!bFound)
  1600. {
  1601. SpeedTable[SupportedSpeeds]=ResultingSpeed;
  1602. SupportedSpeeds++;
  1603. Speed=ResultingSpeed-2352*75;
  1604. }
  1605. else
  1606. {
  1607. Speed-=(2352*75);
  1608. bFound=FALSE;
  1609. }
  1610. }
  1611. }
  1612. else
  1613. Speed=0;
  1614. }
  1615. if (SupportedSpeeds>1)
  1616. {
  1617. //Swap entries
  1618. for (int i=0; i<(SupportedSpeeds/2); i++)
  1619. {
  1620. int Help=SpeedTable[i];
  1621. SpeedTable[i]=SpeedTable[SupportedSpeeds-1-i];
  1622. SpeedTable[SupportedSpeeds-1-i]=Help;
  1623. }
  1624. }
  1625. SetCurrentSpeed(LastSpeed);
  1626. break;
  1627. }
  1628. case CDTYPE_PLEXTOR :
  1629. {
  1630. int LastSpeed=GetCurrentSpeed();
  1631. for (int index=1; index<=20; index++)
  1632. {
  1633. SetCurrentSpeed(index*2352*75);
  1634. if (Lasterror()==CDOK)
  1635. {
  1636. int Speed=GetCurrentSpeed();
  1637. if (Lasterror()==CDOK)
  1638. {
  1639. BOOL found=FALSE;
  1640. for (int i=0; i<SupportedSpeeds; i++)
  1641. {
  1642. if (SpeedTable[i]==Speed)
  1643. found=TRUE;
  1644. }
  1645. if (!found)
  1646. {
  1647. SpeedTable[SupportedSpeeds]=Speed;
  1648. SupportedSpeeds++;
  1649. }
  1650. }
  1651. }
  1652. }
  1653. SetCurrentSpeed(LastSpeed);
  1654. break;
  1655. }
  1656. case CDTYPE_NEC :
  1657. {
  1658. break;
  1659. }
  1660. case CDTYPE_PHILIPS :
  1661. case CDTYPE_MATSHITA :
  1662. {
  1663. int LastSpeed=GetCurrentSpeed();
  1664. SpeedTable[0]=-1;
  1665. SupportedSpeeds++;
  1666. for (int index=1; index<8; index++)
  1667. {
  1668. SetCurrentSpeed(2352*75*index);
  1669. if (Lasterror()==CDOK)
  1670. {
  1671. int Speed=GetCurrentSpeed();
  1672. if ((Lasterror()==CDOK) &&
  1673. (Speed==2352*75*index))
  1674. {
  1675. SpeedTable[SupportedSpeeds]=2352*75*index;
  1676. SupportedSpeeds++;
  1677. }
  1678. }
  1679. }
  1680. SetCurrentSpeed(LastSpeed);
  1681. break;
  1682. }
  1683. }
  1684. m_bSpeedTableInitialized=TRUE;
  1685. }
  1686. BYTE CSCSICD::GetSupportedSpeeds()
  1687. {
  1688. return SupportedSpeeds;
  1689. }
  1690. BOOL IsOldPhilips(TDriveInfo *pConfig)
  1691. {
  1692. BOOL bResult=FALSE;
  1693. if (strstr(pConfig->ProductID,"2000"))
  1694. bResult=TRUE;
  1695. if (strstr(pConfig->ProductID,"4020"))
  1696. bResult=TRUE;
  1697. return bResult;
  1698. }
  1699. //return the identifictaion number for the plextor models
  1700. //defined values:
  1701. #define PX4X 0
  1702. #define PX6X 1
  1703. #define PX8X 2
  1704. #define PX12X 3
  1705. #define PX20X 4
  1706. #define PX32X 5
  1707. #define PXR412 6
  1708. #define PX40X 7
  1709. DWORD GetPlextorModel(TDriveInfo *pConfig)
  1710. {
  1711. DWORD dwResult=PX40X;
  1712. char szId[7] = {0};
  1713. strncpy(szId,&pConfig->ProductID[10],6);
  1714. szId[6]=0;
  1715. if (!_stricmp(szId,"W4220T"))
  1716. {
  1717. dwResult=PXR412;
  1718. }
  1719. else
  1720. {
  1721. if (!_stricmp(szId,"W8220T"))
  1722. {
  1723. dwResult=PXR412;
  1724. }
  1725. else
  1726. {
  1727. szId[5]=0;
  1728. if (!_stricmp(szId,"R412C"))
  1729. {
  1730. dwResult=PXR412;
  1731. }
  1732. else
  1733. {
  1734. if (!_stricmp(szId,"R820T"))
  1735. {
  1736. dwResult=PXR412;
  1737. }
  1738. else
  1739. {
  1740. szId[2]=0;
  1741. if (!strcmp(szId,"40"))
  1742. dwResult=PX40X;
  1743. else
  1744. {
  1745. if (!strcmp(szId,"32"))
  1746. dwResult=PX32X;
  1747. else
  1748. {
  1749. if (!strcmp(szId,"20"))
  1750. dwResult=PX20X;
  1751. else
  1752. {
  1753. if (!strcmp(szId,"12"))
  1754. dwResult=PX12X;
  1755. else
  1756. {
  1757. if (!isdigit(szId[1]))
  1758. szId[1]=0;
  1759. if (!strcmp(szId,"8"))
  1760. dwResult=PX8X;
  1761. else
  1762. {
  1763. if (!strcmp(szId,"6"))
  1764. dwResult=PX6X;
  1765. else
  1766. {
  1767. if (!strcmp(szId,"4"))
  1768. dwResult=PX4X;
  1769. }
  1770. }
  1771. }
  1772. }
  1773. }
  1774. }
  1775. }
  1776. }
  1777. }
  1778. }
  1779. return dwResult;
  1780. }
  1781. int CSCSICD::GetCurrentSpeed()
  1782. {
  1783. TDriveMode ModeSenseData;
  1784. int Speed=0;
  1785. switch (MapInfo.GetTypMapping(Config.Type))
  1786. {
  1787. case CDTYPE_TOSHIBA :
  1788. {
  1789. Speed=0;
  1790. break;
  1791. }
  1792. case CDTYPE_TOSHNEW :
  1793. {
  1794. if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,15,0x20,m_hDriveEvent))
  1795. {
  1796. Error=CDASPIError;
  1797. return 0;
  1798. }
  1799. int Index=(ModeSenseData[14] & 0x30)>>4;
  1800. switch (Index)
  1801. {
  1802. case 0 :
  1803. Speed=2352*75;
  1804. break;
  1805. case 1 :
  1806. Speed=2352*75*4;
  1807. break;
  1808. case 2 :
  1809. Speed=2352*75*4;
  1810. break;
  1811. case 3 :
  1812. Speed=-2;
  1813. break;
  1814. }
  1815. break;
  1816. }
  1817. case CDTYPE_SONY :
  1818. case CDTYPE_RICOH :
  1819. case CDTYPE_CYBERDRV :
  1820. {
  1821. if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,34,0x2A,m_hDriveEvent))
  1822. {
  1823. Error=CDASPIError;
  1824. return 0;
  1825. }
  1826. Speed=(ModeSenseData[26]*256+ModeSenseData[27])*1000;
  1827. break;
  1828. }
  1829. case CDTYPE_ATAPI :
  1830. {
  1831. if (!ATAPIModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,34,0x2A,m_hDriveEvent))
  1832. {
  1833. Error=CDASPIError;
  1834. return 0;
  1835. }
  1836. if ((ModeSenseData[8]&0x3F)==0x2A)
  1837. Speed=(ModeSenseData[22]*256+ModeSenseData[23])*1000;
  1838. else if ((ModeSenseData[4]&0x3F)==0x2A)
  1839. Speed=(ModeSenseData[18]*256+ModeSenseData[19])*1000;
  1840. else Speed=-1;
  1841. break;
  1842. }
  1843. case CDTYPE_PLEXTOR :
  1844. {
  1845. DWORD dwModel=GetPlextorModel(&Config);
  1846. if (dwModel!=PXR412)
  1847. {
  1848. if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,16,0x31,m_hDriveEvent))
  1849. {
  1850. Error=CDASPIError;
  1851. return 0;
  1852. }
  1853. int Index=ModeSenseData[14];
  1854. switch (dwModel)
  1855. {
  1856. case PX4X :
  1857. {
  1858. switch (Index)
  1859. {
  1860. case 0 :
  1861. Speed=2352*75;
  1862. break;
  1863. case 1 :
  1864. Speed=2352*75*2;
  1865. break;
  1866. case 2 :
  1867. Speed=2352*75*4;
  1868. break;
  1869. default :
  1870. Speed=-1;
  1871. break;
  1872. }
  1873. break;
  1874. }
  1875. case PX6X :
  1876. {
  1877. switch (Index)
  1878. {
  1879. case 0 :
  1880. Speed=2352*75;
  1881. break;
  1882. case 1 :
  1883. Speed=2352*75*4;
  1884. break;
  1885. case 2 :
  1886. Speed=2352*75*6;
  1887. break;
  1888. default :
  1889. Speed=-1;
  1890. break;
  1891. }
  1892. break;
  1893. }
  1894. case PX8X :
  1895. {
  1896. switch (Index)
  1897. {
  1898. case 0 :
  1899. Speed=2352*75;
  1900. break;
  1901. case 1 :
  1902. Speed=2352*75*2;
  1903. break;
  1904. case 2 :
  1905. Speed=2352*75*4;
  1906. break;
  1907. case 3 :
  1908. Speed=2352*75*8;
  1909. break;
  1910. default :
  1911. Speed=-1;
  1912. break;
  1913. }
  1914. break;
  1915. }
  1916. case PX12X :
  1917. {
  1918. switch (Index)
  1919. {
  1920. case 0 :
  1921. Speed=2352*75;
  1922. break;
  1923. case 1 :
  1924. Speed=2352*75*2;
  1925. break;
  1926. case 2 :
  1927. Speed=2352*75*4;
  1928. break;
  1929. case 3 :
  1930. Speed=2352*75*8;
  1931. break;
  1932. case 4 :
  1933. Speed=2352*75*8;
  1934. break;
  1935. case 5 :
  1936. Speed=2352*75*12;
  1937. break;
  1938. default :
  1939. Speed=-1;
  1940. break;
  1941. }
  1942. break;
  1943. }
  1944. case PX20X :
  1945. {
  1946. switch (Index)
  1947. {
  1948. case 0 :
  1949. Speed=2352*75;
  1950. break;
  1951. case 1 :
  1952. Speed=2352*75*2;
  1953. break;
  1954. case 2 :
  1955. Speed=2352*75*4;
  1956. break;
  1957. case 3 :
  1958. Speed=2352*75*8;
  1959. break;
  1960. case 4 :
  1961. Speed=2352*75*8;
  1962. break;
  1963. case 5 :
  1964. Speed=-2;
  1965. break;
  1966. case 6 :
  1967. Speed=2352*75*12;
  1968. break;
  1969. default :
  1970. Speed=-1;
  1971. break;
  1972. }
  1973. break;
  1974. }
  1975. case PX32X :
  1976. {
  1977. switch (Index)
  1978. {
  1979. case 0 :
  1980. Speed=2352*75;
  1981. break;
  1982. case 1 :
  1983. Speed=2352*75*2;
  1984. break;
  1985. case 2 :
  1986. Speed=2352*75*4;
  1987. break;
  1988. case 3 :
  1989. Speed=2352*75*8;
  1990. break;
  1991. case 4 :
  1992. Speed=2352*75*8;
  1993. break;
  1994. case 5 :
  1995. Speed=2352*75*8;
  1996. break;
  1997. case 6 :
  1998. Speed=2352*75*14;
  1999. break;
  2000. default :
  2001. Speed=-1;
  2002. break;
  2003. }
  2004. break;
  2005. }
  2006. case PX40X :
  2007. {
  2008. switch (Index)
  2009. {
  2010. case 0 :
  2011. Speed=2352*75;
  2012. break;
  2013. case 1 :
  2014. Speed=2352*75*2;
  2015. break;
  2016. case 2 :
  2017. Speed=2352*75*4;
  2018. break;
  2019. case 3 :
  2020. Speed=2352*75*8;
  2021. break;
  2022. case 4 :
  2023. Speed=2352*75*8;
  2024. break;
  2025. case 5 :
  2026. Speed=2352*75*10;
  2027. break;
  2028. case 6 :
  2029. Speed=2352*75*17;
  2030. break;
  2031. default :
  2032. Speed=-1;
  2033. break;
  2034. }
  2035. break;
  2036. }
  2037. }
  2038. }
  2039. else
  2040. {
  2041. if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,32,0x2A,m_hDriveEvent))
  2042. {
  2043. Error=CDASPIError;
  2044. return 0;
  2045. }
  2046. Speed=(ModeSenseData[26]*256+ModeSenseData[27])*1000;
  2047. }
  2048. break;
  2049. }
  2050. case CDTYPE_NEC :
  2051. {
  2052. if (!addModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,12,m_hDriveEvent))
  2053. {
  2054. Error=CDASPIError;
  2055. return 0;
  2056. }
  2057. // Speed=ModeSenseData[6] & 0x20;
  2058. break;
  2059. }
  2060. case CDTYPE_PHILIPS :
  2061. case CDTYPE_MATSHITA :
  2062. {
  2063. if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,20,0x23,m_hDriveEvent))
  2064. {
  2065. Error=CDASPIError;
  2066. return 0;
  2067. }
  2068. int Index;
  2069. if (IsOldPhilips(&Config))
  2070. Index=ModeSenseData[14];
  2071. else
  2072. Index=ModeSenseData[16];
  2073. switch (Index)
  2074. {
  2075. case 0 :
  2076. Speed=-1;
  2077. break;
  2078. case 1 :
  2079. Speed=2352*75;
  2080. break;
  2081. case 2 :
  2082. Speed=2352*75*2;
  2083. break;
  2084. case 4 :
  2085. Speed=2352*75*4;
  2086. break;
  2087. case 6 :
  2088. Speed=2352*75*6;
  2089. break;
  2090. case 8 :
  2091. Speed=2352*75*8;
  2092. break;
  2093. default :
  2094. Speed=-2;
  2095. }
  2096. break;
  2097. }
  2098. default :
  2099. Speed=0;
  2100. }
  2101. return Speed;
  2102. }
  2103. void CSCSICD::SetCurrentSpeed(int Speed)
  2104. {
  2105. TDriveMode ModeSenseData;
  2106. if (Speed==0)
  2107. return;
  2108. switch (MapInfo.GetTypMapping(Config.Type))
  2109. {
  2110. case CDTYPE_TOSHIBA :
  2111. break;
  2112. case CDTYPE_TOSHNEW :
  2113. {
  2114. if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,15,0x20,m_hDriveEvent))
  2115. {
  2116. Error=CDASPIError;
  2117. return;
  2118. }
  2119. ModeSenseData[0]=0;
  2120. int Index;
  2121. switch (Speed)
  2122. {
  2123. case -2 :
  2124. Index=3;
  2125. break;
  2126. case 2352*75 :
  2127. Index=0;
  2128. break;
  2129. case 2352*75*4 :
  2130. Index=1;
  2131. break;
  2132. default :
  2133. Index=2;
  2134. }
  2135. ModeSenseData[14]=(ModeSenseData[14] & 0xcf)|(Index<<4);
  2136. if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,15,m_hDriveEvent))
  2137. Error=CDASPIError;
  2138. break;
  2139. }
  2140. case CDTYPE_SONY :
  2141. case CDTYPE_RICOH :
  2142. case CDTYPE_CYBERDRV :
  2143. case CDTYPE_ATAPI :
  2144. {
  2145. TOpcode OpC;
  2146. OpC[0]=0xbb;
  2147. OpC[1]=0x00;
  2148. OpC[4]=0x00;
  2149. OpC[5]=0x00;
  2150. OpC[6]=0x00;
  2151. OpC[7]=0x00;
  2152. OpC[8]=0x00;
  2153. OpC[9]=0x00;
  2154. OpC[10]=0x00;
  2155. OpC[11]=0x00;
  2156. int NewSpeed=Speed/1000;
  2157. int ModSpeed=NewSpeed*1000;
  2158. int Direction=0;
  2159. int AktSpeed=0;
  2160. int Counter=0;
  2161. do
  2162. {
  2163. Error=CDOK;
  2164. Counter++;
  2165. NewSpeed+=Direction;
  2166. OpC[2]=NewSpeed/256;
  2167. OpC[3]=NewSpeed%256;
  2168. if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_OUT,OpC,12,NULL,0,m_hDriveEvent))
  2169. Error=CDASPIError;
  2170. // Is the speed really the one we have selected?
  2171. AktSpeed=GetCurrentSpeed();
  2172. if (!Direction)
  2173. {
  2174. if (AktSpeed<Speed)
  2175. Direction=1;
  2176. else if (AktSpeed>Speed)
  2177. Direction=-1;
  2178. }
  2179. }
  2180. while ((AktSpeed!=ModSpeed) && NewSpeed && (Counter<3));
  2181. break;
  2182. }
  2183. case CDTYPE_PLEXTOR :
  2184. {
  2185. DWORD dwModel=GetPlextorModel(&Config);
  2186. if (dwModel!=PXR412)
  2187. {
  2188. if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,16,0x31,m_hDriveEvent))
  2189. {
  2190. Error=CDASPIError;
  2191. return;
  2192. }
  2193. int Index;
  2194. switch (dwModel)
  2195. {
  2196. case PX4X :
  2197. {
  2198. switch (Speed)
  2199. {
  2200. case 2352*75 :
  2201. Index=0;
  2202. break;
  2203. case 2352*75*2 :
  2204. Index=1;
  2205. break;
  2206. case -1 :
  2207. case 2352*75*4 :
  2208. Index=2;
  2209. break;
  2210. default :
  2211. Index=-1;
  2212. break;
  2213. }
  2214. break;
  2215. }
  2216. case PX6X :
  2217. {
  2218. switch (Speed)
  2219. {
  2220. case 2352*75 :
  2221. Index=0;
  2222. break;
  2223. case 2352*75*4 :
  2224. Index=1;
  2225. break;
  2226. case -1 :
  2227. case 2352*75*6 :
  2228. Index=2;
  2229. break;
  2230. default :
  2231. Index=-1;
  2232. break;
  2233. }
  2234. break;
  2235. }
  2236. case PX8X :
  2237. {
  2238. switch (Speed)
  2239. {
  2240. case 2352*75 :
  2241. Index=0;
  2242. break;
  2243. case 2352*75*2 :
  2244. Index=1;
  2245. break;
  2246. case 2352*75*4 :
  2247. Index=2;
  2248. break;
  2249. case -1 :
  2250. case 2352*75*8 :
  2251. Index=3;
  2252. break;
  2253. default :
  2254. Index=-1;
  2255. break;
  2256. }
  2257. break;
  2258. }
  2259. case PX12X :
  2260. {
  2261. switch (Speed)
  2262. {
  2263. case 2352*75 :
  2264. Index=0;
  2265. break;
  2266. case 2352*75*2 :
  2267. Index=1;
  2268. break;
  2269. case 2352*75*4 :
  2270. Index=2;
  2271. break;
  2272. case 2352*75*8 :
  2273. Index=3;
  2274. break;
  2275. case -1 :
  2276. case 2352*75*12 :
  2277. Index=5;
  2278. break;
  2279. default :
  2280. Index=-1;
  2281. break;
  2282. }
  2283. break;
  2284. }
  2285. case PX20X :
  2286. {
  2287. switch (Speed)
  2288. {
  2289. case 2352*75 :
  2290. Index=0;
  2291. break;
  2292. case 2352*75*2 :
  2293. Index=1;
  2294. break;
  2295. case 2352*75*4 :
  2296. Index=2;
  2297. break;
  2298. case 2352*75*8 :
  2299. Index=3;
  2300. break;
  2301. case -1 :
  2302. case 2352*75*12 :
  2303. Index=6;
  2304. break;
  2305. default :
  2306. Index=-1;
  2307. break;
  2308. }
  2309. break;
  2310. }
  2311. case PX32X :
  2312. {
  2313. switch (Speed)
  2314. {
  2315. case 2352*75 :
  2316. Index=0;
  2317. break;
  2318. case 2352*75*2 :
  2319. Index=1;
  2320. break;
  2321. case 2352*75*4 :
  2322. Index=2;
  2323. break;
  2324. case 2352*75*8 :
  2325. Index=3;
  2326. break;
  2327. case -1 :
  2328. case 2352*75*14 :
  2329. Index=6;
  2330. break;
  2331. default :
  2332. Index=-1;
  2333. break;
  2334. }
  2335. break;
  2336. }
  2337. case PX40X :
  2338. {
  2339. switch (Speed)
  2340. {
  2341. case 2352*75 :
  2342. Index=0;
  2343. break;
  2344. case 2352*75*2 :
  2345. Index=1;
  2346. break;
  2347. case 2352*75*4 :
  2348. Index=2;
  2349. break;
  2350. case 2352*75*8 :
  2351. Index=3;
  2352. break;
  2353. case 2352*75*10 :
  2354. Index=5;
  2355. break;
  2356. case -1 :
  2357. case 2352*75*17 :
  2358. Index=6;
  2359. break;
  2360. default :
  2361. Index=-1;
  2362. break;
  2363. }
  2364. break;
  2365. }
  2366. }
  2367. if (Index>=0)
  2368. {
  2369. ModeSenseData[14]=Index;
  2370. if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,16,m_hDriveEvent))
  2371. Error=CDASPIError;
  2372. }
  2373. else
  2374. Error=CDASPIError;
  2375. }
  2376. else
  2377. {
  2378. TOpcode OpC;
  2379. OpC[0]=0xbb;
  2380. OpC[1]=0x00;
  2381. OpC[4]=0xff;
  2382. OpC[5]=0xff;
  2383. OpC[6]=0x00;
  2384. OpC[7]=0x00;
  2385. OpC[8]=0x00;
  2386. OpC[9]=0x00;
  2387. OpC[10]=0x00;
  2388. OpC[11]=0x00;
  2389. int NewSpeed=Speed/1000;
  2390. int ModSpeed=NewSpeed*1000;
  2391. int Direction=0;
  2392. int AktSpeed=0;
  2393. int Counter=0;
  2394. do
  2395. {
  2396. Error=CDOK;
  2397. Counter++;
  2398. NewSpeed+=Direction;
  2399. OpC[2]=NewSpeed/256;
  2400. OpC[3]=NewSpeed%256;
  2401. if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_OUT,OpC,12,NULL,0,m_hDriveEvent))
  2402. Error=CDASPIError;
  2403. // Is the speed really the one we have selected?
  2404. AktSpeed=GetCurrentSpeed();
  2405. if (!Direction)
  2406. {
  2407. if (AktSpeed<Speed)
  2408. Direction=1;
  2409. else if (AktSpeed>Speed)
  2410. Direction=-1;
  2411. }
  2412. }
  2413. while ((AktSpeed!=ModSpeed) && NewSpeed && (Counter<3));
  2414. }
  2415. break;
  2416. }
  2417. case CDTYPE_NEC :
  2418. {
  2419. if (!addModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,12,m_hDriveEvent))
  2420. {
  2421. Error=CDASPIError;
  2422. return;
  2423. }
  2424. // Speed=ModeSenseData[6] & 0x20;
  2425. if (!addModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,12,m_hDriveEvent))
  2426. Error=CDASPIError;
  2427. break;
  2428. }
  2429. case CDTYPE_PHILIPS :
  2430. case CDTYPE_MATSHITA :
  2431. {
  2432. if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,20,0x23,m_hDriveEvent))
  2433. {
  2434. Error=CDASPIError;
  2435. return;
  2436. }
  2437. ModeSenseData[0]=0;
  2438. int Index;
  2439. switch (Speed)
  2440. {
  2441. case -2 :
  2442. case -1 :
  2443. Index=0;
  2444. break;
  2445. case 2352*75 :
  2446. Index=1;
  2447. break;
  2448. case 2352*75*2 :
  2449. Index=2;
  2450. break;
  2451. case 2352*75*4 :
  2452. Index=4;
  2453. break;
  2454. case 2352*75*6 :
  2455. Index=6;
  2456. break;
  2457. case 2352*75*8 :
  2458. Index=8;
  2459. break;
  2460. default :
  2461. Index=0;
  2462. }
  2463. if (IsOldPhilips(&Config))
  2464. ModeSenseData[14]=Index;
  2465. else
  2466. ModeSenseData[16]=Index;
  2467. if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,20,m_hDriveEvent))
  2468. Error=CDASPIError;
  2469. break;
  2470. }
  2471. }
  2472. }
  2473. int CSCSICD::GetSpeed(BYTE Index)
  2474. {
  2475. if (Index<SupportedSpeeds)
  2476. return SpeedTable[Index];
  2477. return 0;
  2478. }
  2479. // ----------------------------------------------------------------------------------------
  2480. // - Implementation of general functions -
  2481. // - -
  2482. // - Author: Christoph Schmelnik -
  2483. // - Purposee: variour initialisations -
  2484. // ----------------------------------------------------------------------------------------
  2485. extern "C" DWORD NtScsiSendASPI32Command( LPSRB lpsrb );
  2486. int LoadASPI2()
  2487. {
  2488. OSVERSIONINFO VersionInfo;
  2489. VersionInfo.dwOSVersionInfoSize=sizeof(VersionInfo);
  2490. GetVersionEx(&VersionInfo);
  2491. if (VersionInfo.dwPlatformId==VER_PLATFORM_WIN32_NT)
  2492. RunningNT=TRUE;
  2493. else
  2494. RunningNT=FALSE;
  2495. ASPIInstalled=TRUE;
  2496. hDLL=LoadLibrary(L"WNASPI32.DLL"); // load DLL
  2497. if (hDLL==0)
  2498. {
  2499. if(RunningNT) {
  2500. // ok, let's try to see if we can use NT's internal SCSI manager
  2501. extern int NtScsiInit( void );
  2502. int nb;
  2503. if(nb=NtScsiInit()) {
  2504. NumberOfHostAdapters=nb;
  2505. SendASPI32Command=(SRBPROC)&NtScsiSendASPI32Command;
  2506. return TRUE;
  2507. }
  2508. }
  2509. ASPIInstalled=FALSE;
  2510. return FALSE;
  2511. }
  2512. GetASPI32SupportInfo=(VOIDPROC)GetProcAddress(hDLL,"GetASPI32SupportInfo"); // get Address
  2513. SendASPI32Command=(SRBPROC)GetProcAddress(hDLL,"SendASPI32Command"); // get Address
  2514. if (GetASPI32SupportInfo==NULL)
  2515. {
  2516. ASPIInstalled=FALSE;
  2517. return FALSE;
  2518. }
  2519. if (SendASPI32Command==NULL)
  2520. {
  2521. ASPIInstalled=FALSE;
  2522. return FALSE;
  2523. }
  2524. int r=GetASPI32SupportInfo();
  2525. if (HIBYTE(r)!=SS_COMP)
  2526. {
  2527. ASPIInstalled=FALSE;
  2528. return FALSE;
  2529. }
  2530. NumberOfHostAdapters=LOBYTE(r);
  2531. return TRUE;
  2532. }
  2533. int LoadASPI() {
  2534. int ret=0;
  2535. __try {
  2536. ret=LoadASPI2();
  2537. } __except(EXCEPTION_EXECUTE_HANDLER)
  2538. {
  2539. ret=0;
  2540. }
  2541. return ret;
  2542. }
  2543. int FreeASPI()
  2544. {
  2545. extern int NtScsiDeInit( void );
  2546. NtScsiDeInit();
  2547. if (hDLL) FreeLibrary(hDLL);
  2548. hDLL=NULL;
  2549. return TRUE;
  2550. }
  2551. int CheckASPI()
  2552. {
  2553. return ASPIInstalled;
  2554. }