Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1086 lines
33 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. mct.c
  5. Abstract:
  6. Test program for testing Medium Changer drivers. It calls the appropriate
  7. dispatch routines of the changer driver based on the user input, and displays
  8. the output from the driver.
  9. Environment:
  10. User mode
  11. Revision History :
  12. --*/
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <assert.h>
  17. #include <windows.h>
  18. #include <devioctl.h>
  19. #include <ntddchgr.h>
  20. #define _NTSRB_ // to keep srb.h from being included
  21. #include <scsi.h>
  22. #include "mct.h" // Header file for thie file
  23. HANDLE hChanger = INVALID_HANDLE_VALUE; // Handle to the open device
  24. GET_CHANGER_PARAMETERS ChangerParams; // Changer Parameters
  25. BOOLEAN ChangerParamsRead; // Flag to indicate if the changer params
  26. // have been read.
  27. //
  28. // Changer's features flag corresponding to the
  29. // bits set in Features0 and Features1 in the
  30. // changer driver.
  31. //
  32. PUCHAR ChangerFlagStrings0[] = {
  33. "CHANGER_BAR_CODE_SCANNER_INSTALLED",
  34. "CHANGER_INIT_ELEM_STAT_WITH_RANGE",
  35. "CHANGER_CLOSE_IEPORT",
  36. "CHANGER_OPEN_IEPORT",
  37. "CHANGER_STATUS_NON_VOLATILE",
  38. "CHANGER_EXCHANGE_MEDIA",
  39. "CHANGER_CLEANER_SLOT",
  40. "CHANGER_LOCK_UNLOCK",
  41. "CHANGER_CARTRIDGE_MAGAZINE",
  42. "CHANGER_MEDIUM_FLIP",
  43. "CHANGER_POSITION_TO_ELEMENT",
  44. "CHANGER_REPORT_IEPORT_STATE",
  45. "CHANGER_STORAGE_DRIVE",
  46. "CHANGER_STORAGE_IEPORT",
  47. "CHANGER_STORAGE_SLOT",
  48. "CHANGER_STORAGE_TRANSPORT",
  49. "CHANGER_DRIVE_CLEANING_REQUIRED",
  50. "CHANGER_PREDISMOUNT_EJECT_REQUIRED",
  51. "CHANGER_CLEANER_ACCESS_NOT_VALID",
  52. "CHANGER_PREMOUNT_EJECT_REQUIRED",
  53. "CHANGER_VOLUME_IDENTIFICATION",
  54. "CHANGER_VOLUME_SEARCH",
  55. "CHANGER_VOLUME_ASSERT",
  56. "CHANGER_VOLUME_REPLACE",
  57. "CHANGER_VOLUME_UNDEFINE",
  58. "",
  59. "CHANGER_SERIAL_NUMBER_VALID",
  60. "CHANGER_DEVICE_REINITIALIZE_CAPABLE",
  61. "CHANGER_KEYPAD_ENABLE_DISABLE",
  62. "CHANGER_DRIVE_EMPTY_ON_DOOR_ACCESS"
  63. };
  64. PUCHAR ChangerFlagStrings1[] = {
  65. "CHANGER_PREDISMOUNT_ALIGN_TO_SLOT",
  66. "CHANGER_PREDISMOUNT_ALIGN_TO_DRIVE",
  67. "CHANGER_CLEANER_AUTODISMOUNT",
  68. "CHANGER_TRUE_EXCHANGE_CAPABLE",
  69. "CHANGER_SLOTS_USE_TRAYS",
  70. "CHANGER_RTN_MEDIA_TO_ORIGINAL_ADDR",
  71. "CHANGER_CLEANER_OPS_NOT_SUPPORTED",
  72. "CHANGER_IEPORT_USER_CONTROL_OPEN",
  73. "CHANGER_IEPORT_USER_CONTROL_CLOSE",
  74. "CHANGER_MOVE_EXTENDS_IEPORT",
  75. "CHANGER_MOVE_RETRACTS_IEPORT",
  76. };
  77. int __cdecl main(int argc, char *argv[])
  78. {
  79. char switchChar;
  80. BOOLEAN changerOpened;
  81. if (argc == 1) {
  82. mctPrintUsage();
  83. return 0;
  84. }
  85. if (*argv[1] != '-') {
  86. mctPrintUsage();
  87. return 0;
  88. }
  89. //
  90. // If the changer is not open,
  91. // try to open the changer device.
  92. //
  93. if (hChanger == INVALID_HANDLE_VALUE) {
  94. changerOpened = mctOpenChanger();
  95. }
  96. if (changerOpened == FALSE) {
  97. mctDebugPrint(1, "Could not open changer. Aborting!\n");
  98. return 0;
  99. }
  100. //
  101. // Read the changer parameters.
  102. //
  103. /*
  104. if (mctGetParameters(FALSE) != MCT_STATUS_SUCCESS) {
  105. mctDebugPrint(0, "Unable to read changer parameters.\n");
  106. ChangerParamsRead = FALSE;
  107. } else {
  108. ChangerParamsRead = TRUE;
  109. }
  110. */
  111. //
  112. // Get the function to be called.
  113. //
  114. switchChar = *(argv[1]+1);
  115. switch (switchChar) {
  116. case INIT_ELEMENT_STATUS: {
  117. if (mctInitElementStatus() != MCT_STATUS_SUCCESS) {
  118. mctDebugPrint(1, "Error doing InitElement.\n");
  119. }
  120. break;
  121. }
  122. case GET_ELEMENT_STATUS: {
  123. CHAR ElemType;
  124. USHORT ElemAddress;
  125. if (argc != 4) {
  126. mctDebugPrint(0, "GetElementStatus : mct -e ElemType ElemAddress\n");
  127. break;
  128. }
  129. ElemType = (CHAR)toupper(*argv[2]);
  130. ElemAddress = (USHORT)atoi(argv[3]);
  131. if (mctGetElementStatus(ElemType, ElemAddress) != MCT_STATUS_SUCCESS) {
  132. mctDebugPrint(1, "Error doing GetElementStatus.\n");
  133. }
  134. break;
  135. }
  136. case GET_PARAMETERS: {
  137. if (mctGetParameters(TRUE) != MCT_STATUS_SUCCESS) {
  138. mctDebugPrint(1, "Error reading changer parameters.\n");
  139. }
  140. break;
  141. }
  142. case GET_STATUS: {
  143. if (mctGetStatus() != MCT_STATUS_SUCCESS) {
  144. mctDebugPrint(1, "Error doing GetStatus.\n");
  145. }
  146. break;
  147. }
  148. case GET_PRODUCT_DATA: {
  149. if (mctGetProductData() != MCT_STATUS_SUCCESS) {
  150. mctDebugPrint(1, "Error doing GetProductData.\n");
  151. }
  152. break;
  153. }
  154. case SET_ACCESS: {
  155. CHAR ElemType, Control;
  156. USHORT ElemAddr;
  157. if (argc != 5) {
  158. mctDebugPrint(0, "SetAccess : mct -a ElemType ElemAddr Control\n");
  159. break;
  160. }
  161. ElemType = (CHAR)toupper(*argv[2]);
  162. ElemAddr = (USHORT)atoi(argv[3]);
  163. Control = (CHAR)toupper(*argv[4]);
  164. if (mctSetAccess(ElemType, ElemAddr, Control) != MCT_STATUS_SUCCESS) {
  165. mctDebugPrint(1, "Error doing SetAccess.\n");
  166. }
  167. break;
  168. }
  169. case SET_POSITION: {
  170. USHORT Dest;
  171. CHAR ElemType;
  172. if (argc != 4) {
  173. mctDebugPrint(0, "SetPosition: mct -o ElemType Dest\n");
  174. break;
  175. }
  176. ElemType = (CHAR)toupper(*argv[2]);
  177. Dest = (USHORT)atoi(argv[3]);
  178. if (mctSetPosition(ElemType, Dest) != MCT_STATUS_SUCCESS) {
  179. mctDebugPrint(1, "Error doing SetPosition.\n");
  180. }
  181. break;
  182. }
  183. case EXCHANGE_MEDIUM: {
  184. USHORT Transport, Source, Dest1, Dest2;
  185. CHAR TransType, SrcType, Dest1Type, Dest2Type;
  186. if (argc != 10) {
  187. mctDebugPrint(0, "ExchangeMedium: mct -x ElemType Trans ElemType Src ElemType");
  188. mctDebugPrint(0, " Dest1 ElemType Dest2\n");
  189. break;
  190. }
  191. TransType = (CHAR)toupper(*argv[2]);
  192. Transport = (USHORT)atoi(argv[3]);
  193. SrcType = (CHAR)toupper(*argv[4]);
  194. Source = (USHORT)atoi(argv[5]);
  195. Dest1Type = (CHAR)toupper(*argv[6]);
  196. Dest1 = (USHORT)atoi(argv[7]);
  197. Dest2Type = (CHAR)toupper(*argv[8]);
  198. Dest2 = (USHORT)atoi(argv[9]);
  199. if (mctExchangeMedium(TransType, Transport,
  200. SrcType, Source,
  201. Dest1Type, Dest1,
  202. Dest2Type, Dest2) != MCT_STATUS_SUCCESS) {
  203. mctDebugPrint(1, "Error doing Exchange Medium.\n");
  204. }
  205. break;
  206. }
  207. case MOVE_MEDIUM: {
  208. USHORT Transport, Source, Dest;
  209. CHAR TransType, SourceType, DestType;
  210. if (argc != 8) {
  211. mctDebugPrint(0, "MoveMedium : mct -m t N s\\d N s\\d N\n");
  212. break;
  213. }
  214. Transport = (USHORT)atoi(argv[3]);
  215. Source = (USHORT)atoi(argv[5]);
  216. Dest = (USHORT)atoi(argv[7]);
  217. TransType = (CHAR)toupper(*argv[2]);
  218. SourceType = (CHAR)toupper(*argv[4]);
  219. DestType = (CHAR)toupper(*argv[6]);
  220. if (mctMoveMedium(TransType, Transport, SourceType, Source,
  221. DestType, Dest) != MCT_STATUS_SUCCESS) {
  222. mctDebugPrint(1, "Error doing Move Medium.\n");
  223. }
  224. break;
  225. }
  226. case REINITIALIZE_TRANSPORT: {
  227. if (mctReinitTransport() != MCT_STATUS_SUCCESS) {
  228. mctDebugPrint(1, "Error doing Reinitialize Transport.\n");
  229. }
  230. break;
  231. }
  232. case QUERY_VOLUME_TAG: {
  233. if (mctQueryVolumeTag() != MCT_STATUS_SUCCESS) {
  234. mctDebugPrint(1, "Error doing QueryVolumeTag.\n");
  235. }
  236. break;
  237. }
  238. default: mctPrintUsage();
  239. break;
  240. }
  241. mctCloseChanger();
  242. return 0;
  243. }
  244. VOID
  245. mctPrintUsage()
  246. {
  247. printf("\nUsage : MCT\n");
  248. printf(" -i [InitializeElementStatus]\n");
  249. printf(" -e ElemType ElemAddress [GetElementStatus]\n");
  250. printf(" -s [GetStatus]\n");
  251. printf(" -p [GetParameters]\n");
  252. printf(" -d [GetProductData]\n");
  253. printf(" -a ElemType ElemAddr Control [SetAccess]\n");
  254. printf(" -o ElemType Dest [SetPosition]\n");
  255. printf(" -r [ReinitializeTransport]\n");
  256. printf(" -q [QueryVolumeTag]\n");
  257. printf(" -m ElemType Trans ElemType Src ElemType ");
  258. printf("Dest [MoveMedium]\n");
  259. printf(" -x ElemType Trans ElemType Src ElemType ");
  260. printf("Dest1 ElemType Dest2 [ExchangeMedium]\n");
  261. return;
  262. }
  263. BOOLEAN
  264. mctOpenChanger()
  265. {
  266. DWORD nBytes = 0, nBlockSize;
  267. ULONG retVal;
  268. DWORD status;
  269. UINT ChangerId;
  270. CHAR ChangerName[128];
  271. ChangerId = 0;
  272. //printf("Enter the changer number (0, 1, 2,.., N) : ");
  273. //scanf("%d", &ChangerId);
  274. sprintf(ChangerName, "\\\\.\\Changer%d", ChangerId);
  275. mctDebugPrint(3, "\nOpening changer %s\n", ChangerName);
  276. hChanger = CreateFile(ChangerName, (GENERIC_READ | GENERIC_WRITE),
  277. (FILE_SHARE_READ | FILE_SHARE_WRITE),
  278. NULL, OPEN_EXISTING,
  279. FILE_ATTRIBUTE_NORMAL, NULL);
  280. if (hChanger == INVALID_HANDLE_VALUE) {
  281. mctDebugPrint(0, "Unable to open changer - Error %d. ", GetLastError());
  282. mctDebugPrint(0, "Aborting test!\n");
  283. return FALSE;
  284. }
  285. return TRUE;
  286. }
  287. VOID
  288. mctCloseChanger()
  289. {
  290. if (hChanger != INVALID_HANDLE_VALUE) {
  291. CloseHandle(hChanger);
  292. } else {
  293. mctDebugPrint(0, "Changer not open or invalid handle value.\n");
  294. }
  295. }
  296. MCT_STATUS
  297. mctInitElementStatus()
  298. {
  299. CHANGER_INITIALIZE_ELEMENT_STATUS initElementStatus;
  300. ULONG retVal;
  301. DWORD nBytes;
  302. initElementStatus.ElementList.Element.ElementType = AllElements;
  303. if ((ChangerParams.Features0) & CHANGER_BAR_CODE_SCANNER_INSTALLED) {
  304. initElementStatus.BarCodeScan = TRUE;
  305. } else {
  306. initElementStatus.BarCodeScan = FALSE;
  307. }
  308. retVal = DeviceIoControl(hChanger, IOCTL_CHANGER_INITIALIZE_ELEMENT_STATUS,
  309. &initElementStatus,
  310. sizeof(CHANGER_INITIALIZE_ELEMENT_STATUS),
  311. NULL, 0, &nBytes, NULL);
  312. if (retVal == FALSE) {
  313. mctDebugPrint(0, "Error doing Initialize Element Status : %d.\n",
  314. GetLastError());
  315. return MCT_STATUS_FAILED;
  316. }
  317. return MCT_STATUS_SUCCESS;
  318. }
  319. MCT_STATUS
  320. mctGetElementStatus(CHAR ElementType, USHORT ElemAddress)
  321. {
  322. CHANGER_READ_ELEMENT_STATUS readElementStat;
  323. PCHANGER_ELEMENT_STATUS_EX ChangerElementStat, tmpChangerElementStat;
  324. DWORD nBytes;
  325. ULONG retVal;
  326. USHORT NoOfElems;
  327. int i, inx;
  328. readElementStat.VolumeTagInfo = FALSE;
  329. switch (ElementType) {
  330. case CHANGER_ALL_ELEMENTS : {
  331. readElementStat.ElementList.Element.ElementType = AllElements;
  332. readElementStat.ElementList.Element.ElementAddress = 0;
  333. NoOfElems = ChangerParams.NumberTransportElements +
  334. ChangerParams.NumberStorageElements +
  335. ChangerParams.NumberIEElements + 1;
  336. readElementStat.ElementList.NumberOfElements = NoOfElems;
  337. break;
  338. }
  339. case CHANGER_TRANSPORT : {
  340. readElementStat.ElementList.Element.ElementType = ChangerTransport;
  341. readElementStat.ElementList.Element.ElementAddress = ElemAddress;
  342. readElementStat.ElementList.NumberOfElements = 1;
  343. NoOfElems = 1;
  344. break;
  345. }
  346. case CHANGER_SLOT : {
  347. readElementStat.ElementList.Element.ElementType = ChangerSlot;
  348. readElementStat.ElementList.Element.ElementAddress = ElemAddress;
  349. readElementStat.ElementList.NumberOfElements = 1;
  350. NoOfElems = 1;
  351. break;
  352. }
  353. case CHANGER_DRIVE : {
  354. readElementStat.ElementList.Element.ElementType = ChangerDrive;
  355. readElementStat.ElementList.Element.ElementAddress = ElemAddress;
  356. readElementStat.ElementList.NumberOfElements = 1;
  357. readElementStat.VolumeTagInfo = TRUE;
  358. NoOfElems = 1;
  359. break;
  360. }
  361. case CHANGER_IEPORT: {
  362. readElementStat.ElementList.Element.ElementType = ChangerIEPort;
  363. readElementStat.ElementList.Element.ElementAddress = ElemAddress;
  364. readElementStat.ElementList.NumberOfElements = 1;
  365. NoOfElems = 1;
  366. break;
  367. }
  368. default: {
  369. mctDebugPrint(0, "Invalid Element Type. \n");
  370. mctDebugPrint(0, "Valid Types :\n");
  371. mctDebugPrint(0, " All Elements : A or a\n");
  372. mctDebugPrint(0, " Transport : T or t\n");
  373. mctDebugPrint(0, " Slot : S or s\n");
  374. mctDebugPrint(0, " Drive : D or d\n");
  375. mctDebugPrint(0, " IEPort : I or i\n");
  376. return MCT_STATUS_FAILED;
  377. }
  378. } // switch (ElementType)
  379. ChangerElementStat = (PCHANGER_ELEMENT_STATUS_EX)malloc(NoOfElems *
  380. sizeof(CHANGER_ELEMENT_STATUS_EX));
  381. if (ChangerElementStat == NULL) {
  382. mctDebugPrint(0, "Malloc failed for ReadElementStatus.\n");
  383. return MCT_STATUS_FAILED;
  384. }
  385. retVal = DeviceIoControl(hChanger, IOCTL_CHANGER_GET_ELEMENT_STATUS,
  386. &readElementStat,
  387. sizeof(CHANGER_READ_ELEMENT_STATUS),
  388. ChangerElementStat,
  389. (NoOfElems * sizeof(CHANGER_ELEMENT_STATUS_EX)),
  390. &nBytes,
  391. NULL);
  392. if (retVal == FALSE) {
  393. mctDebugPrint(0, "ReadElementStatus failed : %d \n",
  394. GetLastError());
  395. free(ChangerElementStat);
  396. return MCT_STATUS_FAILED;
  397. }
  398. //
  399. // Print Element Status information
  400. //
  401. tmpChangerElementStat = ChangerElementStat;
  402. for (i = 0; i < NoOfElems; i++) {
  403. printf("Element Type : %d, ",
  404. ChangerElementStat->Element.ElementType);
  405. printf("Element Status Flag : 0x%08x\n", ChangerElementStat->Flags);
  406. if ((ChangerElementStat->Flags) & ELEMENT_STATUS_EXCEPT) {
  407. printf("Exception occured. Error %x\n",
  408. ChangerElementStat->ExceptionCode);
  409. }
  410. if ((ChangerElementStat->Flags) & ELEMENT_STATUS_FULL) {
  411. printf("Element has Media.\n");
  412. } else {
  413. printf("Element has no media.\n");
  414. }
  415. if ((ChangerElementStat->Flags) & ELEMENT_STATUS_SVALID) {
  416. printf("SourceElementAddress Type : %d, Address : %ul\n",
  417. ChangerElementStat->SrcElementAddress.ElementType,
  418. ChangerElementStat->SrcElementAddress.ElementAddress);
  419. } else {
  420. printf("SourceElementAddress is not valid.\n");
  421. }
  422. if ((ChangerElementStat->Flags) & ELEMENT_STATUS_ID_VALID) {
  423. printf("Target Id : %x\t", ChangerElementStat->TargetId);
  424. }
  425. if ((ChangerElementStat->Flags) & ELEMENT_STATUS_LUN_VALID) {
  426. printf("LUN : %x", ChangerElementStat->Lun);
  427. }
  428. printf("\n");
  429. if ((ChangerElementStat->Flags) & ELEMENT_STATUS_PVOLTAG) {
  430. printf("Primary Volume Tag : ");
  431. for (inx = 0; inx < MAX_VOLUME_ID_SIZE; inx++) {
  432. printf("%d ", ChangerElementStat->PrimaryVolumeID[inx]);
  433. }
  434. printf("\n");
  435. //
  436. // Add code to print Primary volume tag.
  437. //
  438. } else {
  439. printf("Primary Volume Tag information is not set.\n");
  440. }
  441. if ((ChangerElementStat->Flags) & ELEMENT_STATUS_AVOLTAG) {
  442. printf("Alternate Volume Tag information is valid.\n");
  443. //
  444. // Add code to print Alternate volume tag.
  445. //
  446. } else {
  447. printf("Alternate Volume Tag information is not set.\n");
  448. }
  449. ChangerElementStat++;
  450. }
  451. free(tmpChangerElementStat);
  452. return MCT_STATUS_SUCCESS;
  453. }
  454. MCT_STATUS
  455. mctGetStatus()
  456. {
  457. ULONG retVal;
  458. DWORD nBytes;
  459. retVal = DeviceIoControl(hChanger, IOCTL_CHANGER_GET_STATUS,
  460. NULL, 0, NULL, 0, &nBytes, NULL);
  461. if (retVal == FALSE) {
  462. mctDebugPrint(0, "Error reading changer status : %d\n",
  463. GetLastError());
  464. return MCT_STATUS_FAILED;
  465. }
  466. return MCT_STATUS_SUCCESS;
  467. }
  468. MCT_STATUS
  469. mctGetProductData()
  470. {
  471. PCHANGER_PRODUCT_DATA productData;
  472. ULONG retVal;
  473. DWORD nBytes;
  474. CHAR SerialNum[SERIAL_NUMBER_LENGTH+1];
  475. productData = (PCHANGER_PRODUCT_DATA)calloc(1, sizeof(CHANGER_PRODUCT_DATA));
  476. retVal = DeviceIoControl(hChanger, IOCTL_CHANGER_GET_PRODUCT_DATA,
  477. NULL, 0,
  478. productData,
  479. sizeof(CHANGER_PRODUCT_DATA),
  480. &nBytes, NULL);
  481. if (retVal == FALSE) {
  482. mctDebugPrint(0, "Error reading product data : %d\n",
  483. GetLastError());
  484. free(productData);
  485. return MCT_STATUS_FAILED;
  486. }
  487. productData->VendorId[VENDOR_ID_LENGTH - 1] = '\0';
  488. productData->ProductId[PRODUCT_ID_LENGTH - 1] = '\0';
  489. productData->Revision[REVISION_LENGTH - 1] = '\0';
  490. strncpy(SerialNum, productData->SerialNumber, SERIAL_NUMBER_LENGTH);
  491. printf("Product Data for Medium Changer device : \n");
  492. printf(" Vendor Id : %s\n", productData->VendorId);
  493. printf(" Product Id : %s\n", productData->ProductId);
  494. printf(" Revision : %s\n", productData->Revision);
  495. printf(" SerialNumber : %s\n", SerialNum);
  496. free(productData);
  497. return MCT_STATUS_SUCCESS;
  498. }
  499. MCT_STATUS
  500. mctSetAccess(CHAR ElementType, USHORT ElemAddr, CHAR Control)
  501. {
  502. CHANGER_SET_ACCESS setAccess;
  503. DWORD nBytes;
  504. ULONG retVal;
  505. switch (ElementType) {
  506. case CHANGER_IEPORT : {
  507. setAccess.Element.ElementType = ChangerIEPort;
  508. setAccess.Element.ElementAddress = ElemAddr;
  509. if (Control == CHANGER_RETRACT_IEPORT) {
  510. setAccess.Control = RETRACT_IEPORT;
  511. } else if (Control == CHANGER_EXTEND_IEPORT) {
  512. setAccess.Control = EXTEND_IEPORT;
  513. } else if (Control == CHANGER_LOCK_ELEMENT) {
  514. setAccess.Control = LOCK_ELEMENT;
  515. } else if ((Control == CHANGER_UNLOCK_ELEMENT)) {
  516. setAccess.Control = UNLOCK_ELEMENT;
  517. } else {
  518. mctDebugPrint(0, "Invalid Control type in SetAccess\n");
  519. mctDebugPrint(0, "Valid types are R\\r or E\\e or L\\l or U\\u \n");
  520. return MCT_STATUS_FAILED;
  521. }
  522. break;
  523. }
  524. case CHANGER_DOOR : {
  525. setAccess.Element.ElementType = ChangerDoor;
  526. setAccess.Element.ElementAddress = ElemAddr;
  527. if (Control == CHANGER_LOCK_ELEMENT) {
  528. setAccess.Control = LOCK_ELEMENT;
  529. } else if (Control == CHANGER_UNLOCK_ELEMENT) {
  530. setAccess.Control = UNLOCK_ELEMENT;
  531. } else {
  532. mctDebugPrint(0, "Invalid Control type in SetAccess\n");
  533. mctDebugPrint(0, " Valid types are L\\l or U\\u \n");
  534. return MCT_STATUS_FAILED;
  535. }
  536. break;
  537. }
  538. case CHANGER_KEYPAD : {
  539. setAccess.Element.ElementType = ChangerKeypad;
  540. setAccess.Element.ElementAddress = ElemAddr;
  541. if (Control == CHANGER_LOCK_ELEMENT) {
  542. setAccess.Control = LOCK_ELEMENT;
  543. } else if (Control == CHANGER_UNLOCK_ELEMENT) {
  544. setAccess.Control = UNLOCK_ELEMENT;
  545. } else {
  546. mctDebugPrint(0, "Invalid Control type in SetAccess\n");
  547. mctDebugPrint(0, " Valid types are L\\l or U\\u \n");
  548. return MCT_STATUS_FAILED;
  549. }
  550. break;
  551. }
  552. default: {
  553. mctDebugPrint(0, "Invalid ElementType for SetAccess.\n");
  554. mctDebugPrint(0, "Valid Type : \n");
  555. mctDebugPrint(0, " IEPort : I or i\n");
  556. mctDebugPrint(0, " Door : O or o\n");
  557. mctDebugPrint(0, " KeyPad : K or k\n");
  558. return MCT_STATUS_FAILED;
  559. }
  560. } // switch (ElementType)
  561. retVal = DeviceIoControl(hChanger, IOCTL_CHANGER_SET_ACCESS,
  562. &setAccess, sizeof(CHANGER_SET_ACCESS),
  563. NULL, 0, &nBytes, NULL);
  564. if (retVal == FALSE) {
  565. mctDebugPrint(0, "Error doing SetAccess : %d\n",
  566. GetLastError());
  567. return MCT_STATUS_FAILED;
  568. }
  569. return MCT_STATUS_SUCCESS;
  570. }
  571. MCT_STATUS
  572. mctSetPosition(CHAR ElemType, USHORT Dest)
  573. {
  574. CHANGER_SET_POSITION setPosition;
  575. DWORD nBytes;
  576. ULONG retVal;
  577. setPosition.Transport.ElementType = ChangerTransport;
  578. setPosition.Transport.ElementAddress = 0;
  579. if (ElemType == CHANGER_SLOT) {
  580. setPosition.Destination.ElementType = ChangerSlot;
  581. } else if (ElemType == CHANGER_DRIVE) {
  582. setPosition.Destination.ElementType = ChangerDrive;
  583. } else if (ElemType == CHANGER_IEPORT) {
  584. setPosition.Destination.ElementType = ChangerIEPort;
  585. } else {
  586. mctDebugPrint(0, "Invalid element type in SetPosition\n");
  587. mctDebugPrint(0, " Valid element types are S\\s or D\\d \n");
  588. return MCT_STATUS_FAILED;
  589. }
  590. setPosition.Destination.ElementAddress = Dest;
  591. retVal = DeviceIoControl(hChanger, IOCTL_CHANGER_SET_POSITION,
  592. &setPosition,
  593. sizeof (CHANGER_SET_POSITION),
  594. NULL, 0, &nBytes, NULL);
  595. if (retVal == FALSE) {
  596. mctDebugPrint(0, "SetPosition failed : %d \n", GetLastError());
  597. return MCT_STATUS_FAILED;
  598. }
  599. return MCT_STATUS_SUCCESS;
  600. }
  601. MCT_STATUS
  602. mctReinitTransport()
  603. {
  604. CHANGER_ELEMENT changerElem;
  605. ULONG retVal;
  606. DWORD nBytes;
  607. changerElem.ElementType = ChangerTransport;
  608. changerElem.ElementAddress = 0;
  609. retVal = DeviceIoControl(hChanger, IOCTL_CHANGER_REINITIALIZE_TRANSPORT,
  610. &changerElem, sizeof(CHANGER_ELEMENT),
  611. NULL, 0, &nBytes, NULL);
  612. if (retVal == FALSE) {
  613. mctDebugPrint(0, "Error reinitializing transport : %d\n",
  614. GetLastError());
  615. return MCT_STATUS_FAILED;
  616. }
  617. return MCT_STATUS_SUCCESS;
  618. }
  619. MCT_STATUS
  620. mctQueryVolumeTag()
  621. {
  622. mctDebugPrint(0, "QueryVolumeTag function to be implemented.\n");
  623. return MCT_STATUS_SUCCESS;
  624. }
  625. MCT_STATUS
  626. mctExchangeMedium(
  627. CHAR TransType,
  628. USHORT Transport,
  629. CHAR SrcType,
  630. USHORT Source,
  631. CHAR Dest1Type,
  632. USHORT Dest1,
  633. CHAR Dest2Type,
  634. USHORT Dest2)
  635. {
  636. CHANGER_EXCHANGE_MEDIUM ExchangeMedium;
  637. DWORD nBytes;
  638. ULONG retVal;
  639. CHAR ElemType;
  640. if(hChanger == INVALID_HANDLE_VALUE) {
  641. mctDebugPrint(0, "Invalid handle to changer. Aborting!\n");
  642. return MCT_STATUS_FAILED;
  643. }
  644. if (TransType != CHANGER_TRANSPORT) {
  645. mctDebugPrint(0, "Invalid Transport ElementType to ExchangeMedium.\n");
  646. mctDebugPrint(0, " Valid type is T\\t \n");
  647. return MCT_STATUS_FAILED;
  648. }
  649. ExchangeMedium.Transport.ElementType = ChangerTransport;
  650. ExchangeMedium.Transport.ElementAddress = Transport;
  651. if (SrcType == CHANGER_SLOT) {
  652. ExchangeMedium.Source.ElementType = ChangerSlot;
  653. } else if (SrcType == CHANGER_DRIVE) {
  654. ExchangeMedium.Source.ElementType = ChangerDrive;
  655. } else {
  656. mctDebugPrint(0, "Invalid Source ElementType to ExchangeMedium.\n");
  657. mctDebugPrint(0, " Valid types are S\\s or D\\d \n");
  658. return MCT_STATUS_FAILED;
  659. }
  660. ExchangeMedium.Source.ElementAddress = Source;
  661. if (Dest1Type == CHANGER_SLOT) {
  662. ExchangeMedium.Destination1.ElementType = ChangerSlot;
  663. } else if (Dest1Type == CHANGER_DRIVE) {
  664. ExchangeMedium.Destination1.ElementType = ChangerDrive;
  665. } else {
  666. mctDebugPrint(0, "Invalid Destination1 ElementType to ExchangeMedium.\n");
  667. mctDebugPrint(0, " Valid types are S\\s or D\\d \n");
  668. return MCT_STATUS_FAILED;
  669. }
  670. ExchangeMedium.Destination1.ElementAddress = Dest1;
  671. if (Dest2Type == CHANGER_SLOT) {
  672. ExchangeMedium.Destination2.ElementType = ChangerSlot;
  673. } else if (Dest2Type == CHANGER_DRIVE) {
  674. ExchangeMedium.Destination2.ElementType = ChangerDrive;
  675. } else {
  676. mctDebugPrint(0, "Invalid Destination2 ElementType to ExchangeMedium.\n");
  677. mctDebugPrint(0, " Valid types are S\\s or D\\d \n");
  678. return MCT_STATUS_FAILED;
  679. }
  680. ExchangeMedium.Destination2.ElementAddress = Dest2;
  681. ExchangeMedium.Flip1 = FALSE;
  682. ExchangeMedium.Flip2 = FALSE;
  683. mctDebugPrint(3, "Exchange : Source - %d, Dest1 - %d, Dest2 - %d",
  684. Source, Dest1, Dest2);
  685. mctDebugPrint(3, " using Transport %d.\n", Transport);
  686. retVal = DeviceIoControl(hChanger, IOCTL_CHANGER_EXCHANGE_MEDIUM,
  687. &ExchangeMedium, sizeof(CHANGER_EXCHANGE_MEDIUM),
  688. NULL, 0, &nBytes, NULL);
  689. if (retVal == FALSE) {
  690. mctDebugPrint(0, "Error doing exchange medium : %d\n", GetLastError());
  691. return MCT_STATUS_FAILED;
  692. }
  693. return MCT_STATUS_SUCCESS;
  694. }
  695. MCT_STATUS
  696. mctMoveMedium(
  697. CHAR TransType,
  698. USHORT Transport,
  699. CHAR SourceType,
  700. USHORT Source,
  701. CHAR DestType,
  702. USHORT Dest)
  703. {
  704. CHANGER_MOVE_MEDIUM MoveMedium;
  705. DWORD nBytes;
  706. ULONG retVal;
  707. USHORT ElemType;
  708. if(hChanger == INVALID_HANDLE_VALUE) {
  709. mctDebugPrint(0, "Invalid handle to changer. Aborting!\n");
  710. return MCT_STATUS_FAILED;
  711. }
  712. if (TransType != CHANGER_TRANSPORT) {
  713. mctDebugPrint(0, "Invalid Transport ElementType to MoveMedium.\n");
  714. mctDebugPrint(0, " Valid type is T\\t \n");
  715. return MCT_STATUS_FAILED;
  716. }
  717. MoveMedium.Transport.ElementType = ChangerTransport;
  718. MoveMedium.Transport.ElementAddress = Transport;
  719. if (SourceType == CHANGER_SLOT) {
  720. mctDebugPrint(3, "Source is a Slot\n");
  721. MoveMedium.Source.ElementType = ChangerSlot;
  722. } else if (SourceType == CHANGER_DRIVE) {
  723. mctDebugPrint(3, "Source is a Drive\n");
  724. MoveMedium.Source.ElementType = ChangerDrive;
  725. } else if (SourceType == CHANGER_IEPORT) {
  726. mctDebugPrint(3, "Source is a IEPort\n");
  727. MoveMedium.Source.ElementType = ChangerIEPort;
  728. }
  729. else {
  730. mctDebugPrint(0, "Invalid Source ElementType to MoveMedium.\n");
  731. mctDebugPrint(0, " Valid types are S\\s or D\\d \n");
  732. return MCT_STATUS_FAILED;
  733. }
  734. MoveMedium.Source.ElementAddress = Source;
  735. if (DestType == CHANGER_SLOT) {
  736. mctDebugPrint(3, "Destination is a Slot\n");
  737. MoveMedium.Destination.ElementType = ChangerSlot;
  738. } else if (DestType == CHANGER_DRIVE) {
  739. mctDebugPrint(3, "Destination is a Drive\n");
  740. MoveMedium.Destination.ElementType = ChangerDrive;
  741. } else if (DestType == CHANGER_IEPORT) {
  742. mctDebugPrint(3, "Destination is a IEPort\n");
  743. MoveMedium.Destination.ElementType = ChangerIEPort;
  744. } else {
  745. mctDebugPrint(0, "Invalid Destination ElementType to MoveMedium.\n");
  746. mctDebugPrint(0, " Valid types are S\\s or D\\d \n");
  747. return MCT_STATUS_FAILED;
  748. }
  749. MoveMedium.Destination.ElementAddress = Dest;
  750. MoveMedium.Flip = FALSE;
  751. mctDebugPrint(3, "Move : Transport - %d, Src - %d, Dest - %d\n",
  752. Transport, Source, Dest);
  753. retVal = DeviceIoControl(hChanger, IOCTL_CHANGER_MOVE_MEDIUM,
  754. &MoveMedium, sizeof(CHANGER_MOVE_MEDIUM),
  755. NULL, 0, &nBytes, NULL);
  756. if (retVal == FALSE) {
  757. mctDebugPrint(0, "Error doing move medium : %d\n", GetLastError());
  758. return MCT_STATUS_FAILED;
  759. }
  760. return MCT_STATUS_SUCCESS;
  761. }
  762. MCT_STATUS
  763. mctGetParameters(BOOLEAN PrintParams)
  764. {
  765. ULONG retVal;
  766. DWORD nBytes;
  767. int i;
  768. DWORD Features;
  769. if(hChanger == INVALID_HANDLE_VALUE) {
  770. mctDebugPrint(0, "Invalid handle to changer. Aborting!\n");
  771. return MCT_STATUS_FAILED;
  772. }
  773. //
  774. // Read changer params only if it hasn't been done already.
  775. //
  776. if (ChangerParamsRead == FALSE) {
  777. //
  778. // Get the parameters for this changer device.
  779. //
  780. retVal = DeviceIoControl(hChanger, IOCTL_CHANGER_GET_PARAMETERS,
  781. NULL, 0, &ChangerParams, sizeof(GET_CHANGER_PARAMETERS),
  782. &nBytes, NULL);
  783. if (retVal == FALSE) {
  784. mctDebugPrint(0, "Error reading changer parametes : %d.\n",
  785. GetLastError());
  786. return MCT_STATUS_FAILED;
  787. }
  788. }
  789. if (PrintParams == FALSE) {
  790. return MCT_STATUS_SUCCESS;
  791. }
  792. //
  793. // Read the parameters of the changer. Display it.
  794. //
  795. printf("\n ********** Changer Parameters ********** \n\n");
  796. printf("\t Number of Transport Elements : %d\n",
  797. ChangerParams.NumberTransportElements);
  798. printf("\t Number of Storage Elements : %d\n",
  799. ChangerParams.NumberStorageElements);
  800. printf("\t Number of Cleaner Slots : %d\n",
  801. ChangerParams.NumberCleanerSlots);
  802. printf("\t Number of of IE Elements : %d\n",
  803. ChangerParams.NumberIEElements);
  804. printf("\t Number of NumberDataTransferElements : %d\n",
  805. ChangerParams.NumberDataTransferElements);
  806. printf("\t Number of Doors : %d\n", ChangerParams.NumberOfDoors);
  807. printf("\n\t First Slot Number : %d\n", ChangerParams.FirstSlotNumber);
  808. printf("\t First Drive Number : %d\n", ChangerParams.FirstDriveNumber);
  809. printf("\t First Transport Number : %d\n",
  810. ChangerParams.FirstTransportNumber);
  811. printf("\t First IEPort number : %d\n", ChangerParams.FirstIEPortNumber);
  812. printf("\t First Cleaner Slot Address : %d\n",
  813. ChangerParams.FirstCleanerSlotAddress);
  814. printf("\n\t Magazine Size : %d\n", ChangerParams.MagazineSize);
  815. printf("\n\t Drive Clean Timeout : %u\n", ChangerParams.DriveCleanTimeout);
  816. printf("\n Flags set for the changer : \n");
  817. Features = ChangerParams.Features0;
  818. for (i = 0; i < 30; i++) {
  819. if (Features & 1) {
  820. printf("\t %s\n", ChangerFlagStrings0[i]);
  821. }
  822. Features >>= 1;
  823. }
  824. Features = ChangerParams.Features1;
  825. for (i = 0; i < 11; i++) {
  826. if (Features & 1) {
  827. printf("\t %s\n", ChangerFlagStrings1[i]);
  828. }
  829. Features >>= 1;
  830. }
  831. PRINT_MOVE_CAPABILITIES(ChangerParams.MoveFromTransport, "Transport");
  832. PRINT_MOVE_CAPABILITIES(ChangerParams.MoveFromSlot, "Slot");
  833. PRINT_MOVE_CAPABILITIES(ChangerParams.MoveFromIePort, "IEPort");
  834. PRINT_MOVE_CAPABILITIES(ChangerParams.MoveFromDrive, "Drive");
  835. PRINT_EXCHANGE_CAPABILITIES(ChangerParams.ExchangeFromTransport, "Transport");
  836. PRINT_EXCHANGE_CAPABILITIES(ChangerParams.ExchangeFromSlot, "Slot");
  837. PRINT_EXCHANGE_CAPABILITIES(ChangerParams.ExchangeFromIePort, "IEPort");
  838. PRINT_EXCHANGE_CAPABILITIES(ChangerParams.ExchangeFromDrive, "Drive");
  839. if ((ChangerParams.Features0) & CHANGER_LOCK_UNLOCK) {
  840. PRINT_LOCK_UNLOCK_CAPABILITY(ChangerParams.LockUnlockCapabilities,
  841. LOCK_UNLOCK_IEPORT, "IEport");
  842. PRINT_LOCK_UNLOCK_CAPABILITY(ChangerParams.LockUnlockCapabilities,
  843. LOCK_UNLOCK_DOOR, "Drive");
  844. PRINT_LOCK_UNLOCK_CAPABILITY(ChangerParams.LockUnlockCapabilities,
  845. LOCK_UNLOCK_KEYPAD, "Keypad");
  846. }
  847. if ((ChangerParams.Features0) & CHANGER_POSITION_TO_ELEMENT) {
  848. PRINT_POSITION_CAPABILITY(ChangerParams.PositionCapabilities,
  849. CHANGER_TO_TRANSPORT, "Transport");
  850. PRINT_POSITION_CAPABILITY(ChangerParams.PositionCapabilities,
  851. CHANGER_TO_SLOT, "Slot");
  852. PRINT_POSITION_CAPABILITY(ChangerParams.PositionCapabilities,
  853. CHANGER_TO_DRIVE, "Drive");
  854. PRINT_POSITION_CAPABILITY(ChangerParams.PositionCapabilities,
  855. CHANGER_TO_IEPORT, "IEPort");
  856. }
  857. return MCT_STATUS_SUCCESS;
  858. }
  859. #if DBG
  860. ULONG mctDebug = 8;
  861. UCHAR DebugBuffer[128];
  862. #endif
  863. #if DBG
  864. VOID
  865. mctDebugPrint(
  866. ULONG DebugPrintLevel,
  867. PCHAR DebugMessage,
  868. ...
  869. )
  870. /*++
  871. Routine Description:
  872. Debug print for all medium changer drivers
  873. Arguments:
  874. Debug print level between 0 and 3, with 3 being the most verbose.
  875. Return Value:
  876. None
  877. --*/
  878. {
  879. va_list ap;
  880. va_start(ap, DebugMessage);
  881. if (DebugPrintLevel <= mctDebug) {
  882. vsprintf(DebugBuffer, DebugMessage, ap);
  883. printf(DebugBuffer);
  884. }
  885. va_end(ap);
  886. } // end mctDebugPrint()
  887. #else
  888. //
  889. // DebugPrint stub
  890. //
  891. VOID
  892. mctDebugPrint(
  893. ULONG DebugPrintLevel,
  894. PCHAR DebugMessage,
  895. ...
  896. )
  897. {
  898. }
  899. #endif