1
0

u3_scsi_spt.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /**
  2. * u3-tool - U3 USB stick manager
  3. * Copyright (C) 2007 Daviedev, daviedev@users.sourceforge.net
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. */
  19. #if HAVE_CONFIG_H
  20. # include "config.h"
  21. #endif
  22. #ifdef SUBSYS_SPT
  23. #include "u3_scsi.h"
  24. #include "u3_error.h"
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #include <stdlib.h>
  28. #include <fcntl.h>
  29. #include <string.h>
  30. #include <unistd.h>
  31. #include <errno.h>
  32. #include <ctype.h>
  33. #include <windows.h>
  34. #include <ddk/ntddscsi.h>
  35. #define U3_TIMEOUT 2 // 2 seconds
  36. const char *u3_subsystem_name = "spt";
  37. const char *u3_subsystem_help = "The drive letter of the device";
  38. int u3_open(u3_handle_t *device, const char *which)
  39. {
  40. HANDLE hDevice;
  41. CHAR lpszDeviceName[7];
  42. DWORD dwBytesReturned;
  43. DWORD dwError;
  44. u3_set_error(device, "");
  45. device->dev = NULL;
  46. // check parameter
  47. if (strlen(which) != 1 || ! isalpha(which[0])) {
  48. u3_set_error(device, "Unknown drive name '%s', Expecting a "
  49. "drive letter", which);
  50. return U3_FAILURE;
  51. }
  52. //take the drive letter and put it in the format used in CreateFile
  53. memcpy(lpszDeviceName, (char *) "\\\\.\\*:", 7);
  54. lpszDeviceName[4] = which[0];
  55. //get a handle to the device, the parameters used here must be used in order for this to work
  56. hDevice=CreateFile(lpszDeviceName,
  57. GENERIC_READ|GENERIC_WRITE,
  58. FILE_SHARE_READ|FILE_SHARE_WRITE,
  59. NULL,
  60. OPEN_EXISTING,
  61. FILE_ATTRIBUTE_NORMAL,
  62. NULL);
  63. //if for some reason we couldn't get a handle to the device we will try again using slightly different parameters for CreateFile
  64. if (hDevice==INVALID_HANDLE_VALUE)
  65. {
  66. u3_set_error(device, "Failed openning handle for %s: Error %d\n", which, GetLastError());
  67. return U3_FAILURE;
  68. }
  69. device->dev = hDevice;
  70. return U3_SUCCESS;
  71. }
  72. void u3_close(u3_handle_t *device)
  73. {
  74. HANDLE hDevice = (HANDLE)device->dev;
  75. CloseHandle(hDevice);
  76. }
  77. int u3_send_cmd(u3_handle_t *device, uint8_t cmd[U3_CMD_LEN],
  78. int dxfer_direction, int dxfer_length, uint8_t *dxfer_data,
  79. uint8_t *status)
  80. {
  81. HANDLE hDevice = (HANDLE)device->dev;
  82. SCSI_PASS_THROUGH_DIRECT sptd;
  83. DWORD returned;
  84. BOOL err;
  85. // translate dxfer_direction
  86. switch (dxfer_direction) {
  87. case U3_DATA_NONE:
  88. dxfer_direction = SCSI_IOCTL_DATA_UNSPECIFIED;
  89. break;
  90. case U3_DATA_TO_DEV:
  91. dxfer_direction = SCSI_IOCTL_DATA_OUT;
  92. break;
  93. case U3_DATA_FROM_DEV:
  94. dxfer_direction = SCSI_IOCTL_DATA_IN;
  95. break;
  96. }
  97. // Prepare command
  98. memset(&sptd, 0, sizeof(SCSI_PASS_THROUGH_DIRECT));
  99. sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);// fixed
  100. sptd.CdbLength = U3_CMD_LEN; // length of command in bytes
  101. sptd.SenseInfoLength = 0; // don't use this currently...
  102. sptd.DataIn = dxfer_direction; // data direction
  103. sptd.DataTransferLength = dxfer_length; // Size of data transfered
  104. sptd.TimeOutValue = U3_TIMEOUT; // timeout in seconds
  105. sptd.DataBuffer = dxfer_data; // data buffer
  106. //sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, sbuf);
  107. memcpy(sptd.Cdb, cmd, U3_CMD_LEN);
  108. // preform ioctl on device
  109. err = DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd,
  110. sizeof(sptd), &sptd, sizeof(sptd), &returned, NULL);
  111. // evaluate result
  112. if (!err) {
  113. u3_set_error(device, "Failed executing scsi command: "
  114. "Error %d", GetLastError());
  115. return U3_FAILURE;
  116. }
  117. *status = sptd.ScsiStatus;
  118. return U3_SUCCESS;
  119. }
  120. #endif // SUBSYS_SPT