ReactOS  0.4.12-dev-14-gd0c8636
atactl.cpp
Go to the documentation of this file.
1 #include <stdarg.h>
2 #include <windef.h>
3 #include <winbase.h>
4 #include <winreg.h>
5 #include <winioctl.h>
6 #include <stdlib.h>
7 //#include <ntdddisk.h>
8 //#include <ntddscsi.h>
9 #include <ntddscsi.h>
10 #include <atapi.h>
11 #include <bm_devs.h>
12 #include <uata_ctl.h>
13 #include <tools.h>
14 #include <uniata_ver.h>
15 
16 #include "helper.h"
17 
18 #define DEFAULT_REMOVAL_LOCK_TIMEOUT 20
19 
20 #define MOV_DW_SWP(a,b) \
21 do \
22 { \
23  *(unsigned short *)&(a) = _byteswap_ushort(*(unsigned short *)&(b)); \
24 } \
25 while (0)
26 
27 #define MOV_DD_SWP(a,b) \
28 { \
29  PFOUR_BYTE _from_, _to_; \
30  _from_ = ((PFOUR_BYTE)&(b)); \
31  _to_ = ((PFOUR_BYTE)&(a)); \
32  __asm mov ebx,_from_ \
33  __asm mov eax,[ebx] \
34  __asm bswap eax \
35  __asm mov ebx,_to_ \
36  __asm mov [ebx],eax \
37 }
38 
39 int g_extended = 0;
41 char* g_bb_list = NULL;
42 int gRadix = 16;
44 
45 BOOLEAN
47  int bus_id,
48  int dev_id,
49  int power_mode
50  );
51 
52 void print_help() {
53  printf("Usage:\n"
54  " atactl -<switches> c|s<controller id>:b<bus id>:d<device id>[:l<lun>]\n"
55  "Switches:\n"
56  " l (L)ist devices on SCSI and ATA controllers bus(es)\n"
57  " Note: ATA Pri/Sec controller are usually represented\n"
58  " as Scsi0/Scsi1 under NT-family OSes\n"
59  " x show e(X)tended info\n"
60  " a show (A)dapter info\n"
61  " s (S)can for new devices on ATA/SATA bus(es) (experimental)\n"
62  " S (S)can for new devices on ATA/SATA bus(es) (experimental)\n"
63  " device, hidden with 'H' can be redetected\n"
64  " h (H)ide device on ATA/SATA bus for removal (experimental)\n"
65  " device can be redetected\n"
66  " H (H)ide device on ATA/SATA bus (experimental)\n"
67  " device can not be redetected until 'h' or 'S' is issued\n"
68  " m [MODE] set i/o (M)ode for device or revert to default\n"
69  " available MODEs are PIO, PIO0-PIO5, DMA, WDMA0-WDMA2,\n"
70  " UDMA33/44/66/100/133, UDMA0-UDMA5\n"
71  " d [XXX] lock ATA/SATA bus for device removal for XXX seconds or\n"
72  " for %d seconds if no lock timeout specified.\n"
73  " can be used with -h, -m or standalone.\n"
74  " D [XXX] disable device (turn into sleep mode) and lock ATA/SATA bus \n"
75  " for device removal for XXX seconds or\n"
76  " for %d seconds if no lock timeout specified.\n"
77  " can be used with -h, -m or standalone.\n"
78  " pX change power state to X, where X is\n"
79  " 0 - active, 1 - idle, 2 - standby, 3 - sleep\n"
80  " r (R)eset device\n"
81  " ba (A)ssign (B)ad-block list\n"
82  " bl get assigned (B)ad-block (L)ist\n"
83  " br (R)eset assigned (B)ad-block list\n"
84  " f specify (F)ile for bad-block list\n"
85  " n XXX block (n)ubmering radix. XXX can be hex or dec\n"
86  "------\n"
87  "Examples:\n"
88  " atactl -l\n"
89  " will list all scsi buses and all connected devices\n"
90  " atactl -m udma0 s2:b1:d1\n"
91  " will switch device at Scsi2, bus 1, taget_id 1 to UDMA0 mode\n"
92  " atactl -h -d 30 c1:b0:d0:l0 \n"
93  " will hide Master (d0:l0) device on secondary (c1:b0) IDE channel\n"
94  " and lock i/o on this channel for 30 seconds to ensure safety\n"
95  " of removal process"
96  "------\n"
97  "Device address format:\n"
98  "\n"
99  "s<controller id> number of controller in system. Is assigned during hardware\n"
100  " detection. Usually s0/s1 are ATA Pri/Sec.\n"
101  " Note, due do NT internal design ATA controllers are represented\n"
102  " as SCSI controllers.\n"
103  "b<bus id> For ATA controllers it is channel number.\n"
104  " Note, usually onboard controller is represented as 2 legacy\n"
105  " ISA-compatible single-channel controllers (Scsi9/Scsi1). Additional\n"
106  " ATA, ATA-RAID and some specific onboard controllers are represented\n"
107  " as multichannel controllers.\n"
108  "d<device id> For ATA controllers d0 is Master, d1 is Slave.\n"
109  "l<lun> Not used in ATA controller drivers, alway 0\n"
110  "------\n"
111  "Bad-block list format:\n"
112  "\n"
113  "# Comment\n"
114  "; Still one comment\n"
115  "hex: switch to hexadecimal mode\n"
116  "<Bad Area 1 Start LBA, e.g. FD50> <Block count 1, e.g. 60>\n"
117  "<Bad Area 2 Start LBA> <Block count 2>\n"
118  "...\n"
119  "dec: switch to decimal mode\n"
120  "<Bad Area N Start LBA, e.g. 16384> <Block count N, e.g. 48>\n"
121  "...\n"
122  "------\n"
123  "",
126  );
127  exit(0);
128 }
129 
130 #define CMD_ATA_LIST 0x01
131 #define CMD_ATA_FIND 0x02
132 #define CMD_ATA_HIDE 0x03
133 #define CMD_ATA_MODE 0x04
134 #define CMD_ATA_RESET 0x05
135 #define CMD_ATA_BBLK 0x06
136 #define CMD_ATA_POWER 0x07
137 
138 HANDLE
140  char* Name
141  )
142 {
143  ULONG i;
144  HANDLE h;
145 
146  for(i=0; i<4; i++) {
147  h = CreateFile(Name,
149  ((i & 1) ? 0 : FILE_SHARE_READ) | ((i & 2) ? 0 : FILE_SHARE_WRITE),
150  NULL,
153  NULL);
154  if(h && (h != ((HANDLE)(-1))) ) {
155  return h;
156  }
157  }
158 
159  for(i=0; i<4; i++) {
160  h = CreateFile(Name,
162  ((i & 1) ? 0 : FILE_SHARE_READ) | ((i & 2) ? 0 : FILE_SHARE_WRITE),
163  NULL,
166  NULL);
167  if(h && (h != ((HANDLE)(-1))) ) {
168  return h;
169  }
170  }
171 
172  for(i=0; i<4; i++) {
173  h = CreateFile(Name,
174  GENERIC_READ,
175  ((i & 1) ? 0 : FILE_SHARE_READ) | ((i & 2) ? 0 : FILE_SHARE_WRITE),
176  NULL,
179  NULL);
180  if(h && (h != ((HANDLE)(-1))) ) {
181  return h;
182  }
183  }
184 
185  for(i=0; i<4; i++) {
186  h = CreateFile(Name,
187  READ_CONTROL,
188  ((i & 1) ? 0 : FILE_SHARE_READ) | ((i & 2) ? 0 : FILE_SHARE_WRITE),
189  NULL,
192  NULL);
193  if(h && (h != ((HANDLE)(-1))) ) {
194  return h;
195  }
196  }
197 
198  return NULL;
199 } // end ata_open_dev()
200 
201 HANDLE
203  char* Name,
205  )
206 {
207  ULONG i;
208  HANDLE h;
209 
210  if(!Name) {
211  if(create) {
213  } else {
215  }
216  }
217 
218  for(i=0; i<4; i++) {
219  h = CreateFile(Name,
220  create ? GENERIC_WRITE : GENERIC_READ ,
221  ((i & 1) ? 0 : FILE_SHARE_READ) | ((i & 2) ? 0 : FILE_SHARE_WRITE),
222  NULL,
223  create ? CREATE_NEW : OPEN_EXISTING,
225  NULL);
226  if(h && (h != ((HANDLE)(-1))) ) {
227  return h;
228  }
229  }
230 
231  return NULL;
232 } // end ata_open_file()
233 
234 void
236  HANDLE h
237  )
238 {
239  CloseHandle(h);
240 } // end ata_close_dev()
241 
242 int
244  HANDLE h,
246  PCCH Signature,
247  ULONG Ioctl,
248  PVOID inBuffer,
249  ULONG inBufferLength,
250  PVOID outBuffer,
251  ULONG outBufferLength,
252  PULONG returned
253  )
254 {
255  ULONG status;
256  PUNIATA_CTL AtaCtl;
257  ULONG data_len = max(inBufferLength, outBufferLength);
258  ULONG len;
259 
260  if(addr) {
261  len = data_len + offsetof(UNIATA_CTL, RawData);
262  } else {
263  len = data_len + sizeof(AtaCtl->hdr);
264  }
265  AtaCtl = (PUNIATA_CTL)GlobalAlloc(GMEM_FIXED, len);
266  AtaCtl->hdr.HeaderLength = sizeof(SRB_IO_CONTROL);
267  if(addr) {
268  AtaCtl->hdr.Length = data_len + offsetof(UNIATA_CTL, RawData) - sizeof(AtaCtl->hdr);
269  } else {
270  AtaCtl->hdr.Length = data_len;
271  }
272 
273  memcpy(&AtaCtl->hdr.Signature, Signature, 8);
274 
275  AtaCtl->hdr.Timeout = 10000;
276  AtaCtl->hdr.ControlCode = Ioctl;
277  AtaCtl->hdr.ReturnCode = 0;
278 
279  if(addr) {
280  AtaCtl->addr = *addr;
281  AtaCtl->addr.Length = sizeof(AtaCtl->addr);
282  }
283 
284  if(outBufferLength) {
285  if(addr) {
286  memset(&AtaCtl->RawData, 0, outBufferLength);
287  } else {
288  memset(&AtaCtl->addr, 0, outBufferLength);
289  }
290  }
291 
292  if(inBuffer && inBufferLength) {
293  if(addr) {
294  memcpy(&AtaCtl->RawData, inBuffer, inBufferLength);
295  } else {
296  memcpy(&AtaCtl->addr, inBuffer, inBufferLength);
297  }
298  }
299 
300  status = DeviceIoControl(h,
302  AtaCtl,
303  len,
304  AtaCtl,
305  len,
306  returned,
307  FALSE);
308 
309  if(outBuffer && outBufferLength) {
310  if(addr) {
311  memcpy(outBuffer, &AtaCtl->RawData, outBufferLength);
312  } else {
313  memcpy(outBuffer, &AtaCtl->addr, outBufferLength);
314  }
315  }
316  GlobalFree(AtaCtl);
317 
318  if(!status) {
319  status = GetLastError();
320  return FALSE;
321  }
322  return TRUE;
323 } // end ata_send_ioctl()
324 
325 int
327  HANDLE h,
329  PCDB cdb,
330  UCHAR cdbLength,
331  PVOID Buffer,
333  BOOLEAN DataIn,
334  PSENSE_DATA senseData,
335  PULONG returned
336  )
337 {
338  ULONG status;
340  //ULONG data_len = BufferLength;
341  ULONG len;
342 
343  len = BufferLength + offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucDataBuf);
344 
346  if(!sptwb) {
347  return FALSE;
348  }
349  memset(sptwb, 0, offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucDataBuf));
350 
351  sptwb->spt.Length = sizeof(SCSI_PASS_THROUGH);
352  sptwb->spt.PathId = addr->PathId;
353  sptwb->spt.TargetId = addr->TargetId;
354  sptwb->spt.Lun = addr->Lun;
355  sptwb->spt.CdbLength = cdbLength;
356  sptwb->spt.SenseInfoLength = 24;
357  sptwb->spt.DataIn = Buffer ? (DataIn ? SCSI_IOCTL_DATA_IN : SCSI_IOCTL_DATA_OUT) : 0;
359  sptwb->spt.TimeOutValue = 10;
360  sptwb->spt.DataBufferOffset =
362  sptwb->spt.SenseInfoOffset =
364  memcpy(&sptwb->spt.Cdb, cdb, cdbLength);
365 
366  if(Buffer && !DataIn) {
367  memcpy(&sptwb->ucSenseBuf, Buffer, BufferLength);
368  }
369 
370  status = DeviceIoControl(h,
372  sptwb,
373  (Buffer && !DataIn) ? len : sizeof(SCSI_PASS_THROUGH),
374  sptwb,
375  (Buffer && DataIn) ? len : offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucDataBuf),
376  returned,
377  FALSE);
378 
379  if(Buffer && DataIn) {
380  memcpy(Buffer, &sptwb->ucDataBuf, BufferLength);
381  }
382  if(senseData) {
383  memcpy(senseData, &sptwb->ucSenseBuf, sizeof(sptwb->ucSenseBuf));
384  }
385 
386  GlobalFree(sptwb);
387 
388  if(!status) {
389  status = GetLastError();
390  return FALSE;
391  }
392  return TRUE;
393 } // end ata_send_scsi()
394 
397 
398 void
400  char* str,
401  int mode
402  )
403 {
404  if(mode > ATA_SA600) {
405  sprintf(str, "SATA-600+");
406  } else
407  if(mode >= ATA_SA600) {
408  sprintf(str, "SATA-600");
409  } else
410  if(mode >= ATA_SA300) {
411  sprintf(str, "SATA-300");
412  } else
413  if(mode >= ATA_SA150) {
414  sprintf(str, "SATA-150");
415  } else
416  if(mode >= ATA_UDMA0) {
417  sprintf(str, "UDMA%d", mode-ATA_UDMA0);
418  } else
419  if(mode >= ATA_WDMA0) {
420  sprintf(str, "WDMA%d", mode-ATA_WDMA0);
421  } else
422  if(mode >= ATA_SDMA0) {
423  sprintf(str, "SDMA%d", mode-ATA_SDMA0);
424  } else
425  if(mode >= ATA_PIO0) {
426  sprintf(str, "PIO%d", mode-ATA_PIO0);
427  } else
428  if(mode == ATA_PIO_NRDY) {
429  sprintf(str, "PIO nRDY");
430  } else
431  {
432  sprintf(str, "PIO");
433  }
434 } // end ata_mode_to_str()
435 
436 #define check_atamode_str(str, mode) \
437  (!_stricmp(str, "UDMA" #mode) || \
438  !_stricmp(str, "UDMA-" #mode) || \
439  !_stricmp(str, "ATA-" #mode) || \
440  !_stricmp(str, "ATA#" #mode))
441 
442 int
444  char* str
445  )
446 {
447  int mode;
448  int len;
449 
450  if(!_stricmp(str, "SATA600"))
451  return ATA_SA600;
452  if(!_stricmp(str, "SATA300"))
453  return ATA_SA300;
454  if(!_stricmp(str, "SATA150"))
455  return ATA_SA150;
456  if(!_stricmp(str, "SATA"))
457  return ATA_SA150;
458 
459  if(check_atamode_str(str, 16))
460  return ATA_UDMA0;
461  if(check_atamode_str(str, 25))
462  return ATA_UDMA1;
463  if(check_atamode_str(str, 33))
464  return ATA_UDMA2;
465  if(check_atamode_str(str, 44))
466  return ATA_UDMA3;
467  if(check_atamode_str(str, 66))
468  return ATA_UDMA4;
469  if(check_atamode_str(str, 100))
470  return ATA_UDMA5;
471  if(check_atamode_str(str, 122))
472  return ATA_UDMA6;
473 
474  len = strlen(str);
475 
476  if(len >= 4 && !_memicmp(str, "UDMA", 4)) {
477  if(len == 4)
478  return ATA_UDMA0;
479  if(len > 5)
480  return -1;
481  mode = str[4] - '0';
482  if(mode < 0 || mode > 7)
483  return -1;
484  return ATA_UDMA0+mode;
485  }
486  if(len >= 4 && !_memicmp(str, "WDMA", 4)) {
487  if(len == 4)
488  return ATA_WDMA0;
489  if(len > 5)
490  return -1;
491  mode = str[4] - '0';
492  if(mode < 0 || mode > 2)
493  return -1;
494  return ATA_WDMA0+mode;
495  }
496  if(len >= 4 && !_memicmp(str, "SDMA", 4)) {
497  if(len == 4)
498  return ATA_SDMA0;
499  if(len > 5)
500  return -1;
501  mode = str[4] - '0';
502  if(mode < 0 || mode > 2)
503  return -1;
504  return ATA_SDMA0+mode;
505  }
506  if(len == 4 && !_memicmp(str, "DMA", 4)) {
507  return ATA_SDMA0;
508  }
509  if(len >= 3 && !_memicmp(str, "PIO", 3)) {
510  if(len == 3)
511  return ATA_PIO;
512  if(len > 4)
513  return -1;
514  mode = str[3] - '0';
515  if(mode < 0 || mode > 5)
516  return -1;
517  return ATA_PIO0+mode;
518  }
519 
520  return -1;
521 } // end ata_str_to_mode()
522 
523 ULONG
525  OUT char* Buffer,
526  IN PUCHAR Str,
527  IN ULONG Length,
528  IN ULONG Xorer
529  )
530 {
531  ULONG i,j;
532  UCHAR a;
533 
534  for(i=0, j=0; i<Length; i++, j++) {
535  a = Str[i ^ Xorer];
536  if(!a) {
537  Buffer[j] = 0;
538  return j;
539  } else
540  if(a == ' ') {
541  Buffer[j] = '_';
542  } else
543  if((a == '_') ||
544  (a == '#') ||
545  (a == '\\') ||
546  (a == '\"') ||
547  (a == '\'') ||
548  (a < ' ') ||
549  (a >= 127)) {
550  Buffer[j] = '#';
551  j++;
552  sprintf(Buffer+j, "%2.2x", a);
553  j++;
554  } else {
555  Buffer[j] = a;
556  }
557  }
558  Buffer[j] = 0;
559  return j;
560 } // end EncodeVendorStr()
561 
562 HKEY
565  OUT char* DevSerial,
566  BOOLEAN read_only
567  )
568 {
569  HKEY hKey = NULL;
570  HKEY hKey2 = NULL;
571  ULONG Length;
572  REGSAM access = read_only ? KEY_READ : KEY_ALL_ACCESS;
573 
574  Length = EncodeVendorStr(DevSerial, (PUCHAR)ident->ModelNumber, sizeof(ident->ModelNumber), 0x01);
575  DevSerial[Length] = '-';
576  Length++;
577  Length += EncodeVendorStr(DevSerial+Length, ident->SerialNumber, sizeof(ident->SerialNumber), 0x01);
578 
579  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\UniATA", NULL, access, &hKey) != ERROR_SUCCESS) {
580  hKey = NULL;
581  goto exit;
582  }
583  if(RegOpenKey(hKey, "Parameters", &hKey2) != ERROR_SUCCESS) {
584  hKey2 = NULL;
585  if(read_only || (RegCreateKey(hKey, "Parameters", &hKey2) != ERROR_SUCCESS)) {
586  hKey2 = NULL;
587  goto exit;
588  }
589  }
590  RegCloseKey(hKey2);
591  if(RegOpenKey(hKey, "Parameters\\BadBlocks", &hKey2) != ERROR_SUCCESS) {
592  hKey2 = NULL;
593  if(read_only || (RegCreateKey(hKey, "Parameters\\BadBlocks", &hKey2) != ERROR_SUCCESS)) {
594  hKey2 = NULL;
595  goto exit;
596  }
597  }
598 
599 exit:
600  if(hKey)
601  RegCloseKey(hKey);
602 
603  return hKey2;
604 } // end ata_get_bblist_regh()
605 
607 
608 int
610  HANDLE h, // handle to ScsiXXX:
611  int dev_id
612  )
613 {
614  ULONG status;
615  ULONG returned;
616 
617  PSCSI_ADAPTER_BUS_INFO adapterInfo;
618  PSCSI_INQUIRY_DATA inquiryData;
620  ULONG i, j;
621  int l_dev_id;
622  ULONG len;
623  GETTRANSFERMODE IoMode;
624  PSENDCMDOUTPARAMS pout;
626  PINQUIRYDATA scsi_ident;
627  char buff[sizeof(SENDCMDOUTPARAMS)+/*sizeof(IDENTIFY_DATA)*/2048];
628  char mode_str[12];
629  //ULONG bus_id = (dev_id >> 24) & 0xff;
630  BOOLEAN found = FALSE;
632  int io_mode = -1;
633  char SerNum[128];
634  char DevSerial[128];
635  char lun_str[10];
636  HKEY hKey2;
637  ULONGLONG max_lba = -1;
638  USHORT chs[3] = { 0 };
639 
640  if(dev_id != -1) {
641  dev_id &= 0x00ffffff;
642  }
643  if(dev_id == 0x007f7f7f) {
644  return TRUE;
645  }
646 
647  pout = (PSENDCMDOUTPARAMS)buff;
648  ident = (PIDENTIFY_DATA)&(pout->bBuffer);
649 
650  status = DeviceIoControl(h,
652  NULL,
653  0,
655  sizeof(g_inquiry_buffer),
656  &returned,
657  FALSE);
658 
659  if(!status) {
660  printf("Can't get device info\n");
661  return FALSE;
662  }
663 
664  // Note: adapterInfo->NumberOfBuses is 1 greater than g_AdapterInfo->NumberChannels
665  // because of virtual communication port
667  for (i = 0; i+1 < adapterInfo->NumberOfBuses; i++) {
668  inquiryData = (PSCSI_INQUIRY_DATA) (g_inquiry_buffer +
669  adapterInfo->BusData[i].InquiryDataOffset);
670 
671  if(g_extended && g_AdapterInfo && g_AdapterInfo->ChanHeaderLengthValid &&
672  g_AdapterInfo->NumberChannels < i) {
673  PCHANINFO ChanInfo;
674 
675  ChanInfo = (PCHANINFO)
676  (((PCHAR)g_AdapterInfo)+
677  sizeof(ADAPTERINFO)+
678  g_AdapterInfo->ChanHeaderLength*i);
679 
680  io_mode = ChanInfo->MaxTransferMode;
681  if(io_mode != -1) {
682  ata_mode_to_str(mode_str, io_mode);
683  } else {
684  mode_str[0] = 0;
685  }
686  printf(" b%lu [%s]\n",
687  i,
688  mode_str
689  );
690  }
691 
692  while (adapterInfo->BusData[i].InquiryDataOffset) {
693  /*
694  if(dev_id/adapterInfo->BusData[i].NumberOfLogicalUnits ==
695  inquiryData->TargetId &&
696  dev_id%adapterInfo->BusData[i].NumberOfLogicalUnits ==
697  inquiryData->Lun) {
698  printf(" %d %d %3d %s %.28s ",
699  i,
700  inquiryData->TargetId,
701  inquiryData->Lun,
702  (inquiryData->DeviceClaimed) ? "Y" : "N",
703  &inquiryData->InquiryData[8]);
704  }*/
705  l_dev_id = (i << 16) | ((ULONG)(inquiryData->TargetId) << 8) | inquiryData->Lun;
706 
707  if(l_dev_id == dev_id || dev_id == -1) {
708 
709  scsi_ident = (PINQUIRYDATA)&(inquiryData->InquiryData);
710  if(!memcmp(&(scsi_ident->VendorId[0]), UNIATA_COMM_PORT_VENDOR_STR, 24)) {
711  // skip communication port
712  goto next_dev;
713  }
714 
715  found = TRUE;
716 
717  if(inquiryData->Lun) {
718  sprintf(lun_str, ":l%d", inquiryData->Lun);
719  } else {
720  sprintf(lun_str, " ");
721  }
722 
723 
724  /*
725  for (j = 0; j < 8; j++) {
726  printf("%02X ", inquiryData->InquiryData[j]);
727  }
728  */
729 
730  addr.Length = sizeof(addr);
731  addr.PortNumber = -1;
732  addr.PathId = inquiryData->PathId;
733  addr.TargetId = inquiryData->TargetId;
734  addr.Lun = inquiryData->Lun;
735  status = ata_send_ioctl(h, &addr, "-UNIATA-",
737  NULL, 0,
738  &IoMode, sizeof(IoMode),
739  &returned);
740  if(status) {
741  //io_mode = min(IoMode.CurrentMode, IoMode.MaxMode);
742  io_mode = IoMode.PhyMode;
743  if(!io_mode) {
744  io_mode = min(max(IoMode.CurrentMode,IoMode.OrigMode),IoMode.MaxMode);
745  }
746  } else {
747  io_mode = -1;
748  }
749 
750  memset(&pin, 0, sizeof(pin));
751  memset(buff, 0, sizeof(buff));
753  // this is valid for IDE/ATA, where only 2 devices can be attached to the bus.
754  // probably, we shall change this in future to support SATA splitters
755  pin.bDriveNumber = inquiryData->PathId*2+inquiryData->TargetId;
756 
757  status = ata_send_ioctl(h, NULL, "SCSIDISK",
759  &pin, sizeof(pin),
760  buff, sizeof(buff),
761  &returned);
762 
763  if(!status) {
764  memset(&pin, 0, sizeof(pin));
765  memset(buff, 0, sizeof(buff));
767  // this is valid for IDE/ATA, where only 2 devices can be attached to the bus.
768  // probably, we shall change this in future to support SATA splitters
769  pin.bDriveNumber = inquiryData->PathId*2+inquiryData->TargetId;
770 
771  status = ata_send_ioctl(h, NULL, "SCSIDISK",
773  &pin, sizeof(pin),
774  buff, sizeof(buff),
775  &returned);
776 
777  }
778 
779  if(!g_extended) {
780  printf(" b%lu:d%d%s %24.24s %4.4s ",
781  i,
782  inquiryData->TargetId,
783  lun_str,
784  /*(inquiryData->DeviceClaimed) ? "Y" : "N",*/
785  (g_extended ? (PUCHAR)"" : &scsi_ident->VendorId[0]),
786  (g_extended ? (PUCHAR)"" : &scsi_ident->ProductRevisionLevel[0])
787  );
788  } else {
789  printf(" b%lu:d%d%s ",
790  i,
791  inquiryData->TargetId,
792  lun_str
793  );
794  }
795 
796  if(status) {
797  if(io_mode == -1) {
798  io_mode = ata_cur_mode_from_ident(ident, IDENT_MODE_ACTIVE);
799  }
800  }
801  if(io_mode != -1) {
802  ata_mode_to_str(mode_str, io_mode);
803  }
804  if(!g_extended || !status) {
805  if(g_extended) {
806  printf(" %24.24s %4.4s ",
807  (&inquiryData->InquiryData[8]),
808  (&inquiryData->InquiryData[8+24])
809  );
810  }
811  if(io_mode != -1) {
812  printf(" %.12s ", mode_str);
813  }
814  }
815  printf("\n");
816 
817  if(g_extended) {
818  if(status) {
819 
820  BOOLEAN BlockMode_valid = TRUE;
821  BOOLEAN print_geom = FALSE;
822 
823  switch(ident->DeviceType) {
824  case ATAPI_TYPE_DIRECT:
825  if(ident->Removable) {
826  printf(" Floppy ");
827  } else {
828  printf(" Hard Drive ");
829  }
830  break;
831  case ATAPI_TYPE_TAPE:
832  printf(" Tape Drive ");
833  break;
834  case ATAPI_TYPE_CDROM:
835  printf(" CD/DVD Drive ");
836  BlockMode_valid = FALSE;
837  break;
838  case ATAPI_TYPE_OPTICAL:
839  printf(" Optical Drive ");
840  BlockMode_valid = FALSE;
841  break;
842  default:
843  printf(" Hard Drive ");
844  print_geom = TRUE;
845  //MOV_DD_SWP(max_lba, ident->UserAddressableSectors);
846  max_lba = ident->UserAddressableSectors;
847  if(ident->FeaturesSupport.Address48) {
848  max_lba = ident->UserAddressableSectors48;
849  }
850  //MOV_DW_SWP(chs[0], ident->NumberOfCylinders);
851  //MOV_DW_SWP(chs[1], ident->NumberOfHeads);
852  //MOV_DW_SWP(chs[2], ident->SectorsPerTrack);
853  chs[0] = ident->NumberOfCylinders;
854  chs[1] = ident->NumberOfHeads;
855  chs[2] = ident->SectorsPerTrack;
856  if(!max_lba) {
857  max_lba = (ULONG)(chs[0])*(ULONG)(chs[1])*(ULONG)(chs[2]);
858  }
859  }
860  if(io_mode != -1) {
861  printf(" %.12s\n", mode_str);
862  }
863  for (j = 0; j < 40; j += 2) {
864  MOV_DW_SWP(SerNum[j], ((PUCHAR)ident->ModelNumber)[j]);
865  }
866  printf(" Mod: %40.40s\n", SerNum);
867  for (j = 0; j < 8; j += 2) {
868  MOV_DW_SWP(SerNum[j], ((PUCHAR)ident->FirmwareRevision)[j]);
869  }
870  printf(" Rev: %8.8s\n", SerNum);
871  for (j = 0; j < 20; j += 2) {
872  MOV_DW_SWP(SerNum[j], ((PUCHAR)ident->SerialNumber)[j]);
873  }
874  printf(" S/N: %20.20s\n", SerNum);
875 
876  if(BlockMode_valid) {
877  if(ident->MaximumBlockTransfer) {
878  printf(" Multi-block mode: %u block%s\n", ident->MaximumBlockTransfer, ident->MaximumBlockTransfer == 1 ? "" : "s");
879  } else {
880  printf(" Multi-block mode: N/A\n");
881  }
882  }
883  if(print_geom) {
884  printf(" C/H/S: %u/%u/%u \n", chs[0], chs[1], chs[2]);
885  printf(" LBA: %I64u \n", max_lba);
886  if(max_lba < 2) {
887  printf(" Size: %lu kb\n", (ULONG)(max_lba/2));
888  } else
889  if(max_lba < 2*1024*1024) {
890  printf(" Size: %lu Mb\n", (ULONG)(max_lba/2048));
891  } else
892  if(max_lba < (ULONG)2*1024*1024*1024) {
893  printf(" Size: %lu.%lu (%lu) Gb\n", (ULONG)(max_lba/2048/1024),
894  (ULONG)(((max_lba/2048)%1024)/10),
895  (ULONG)(max_lba*512/1000/1000/1000)
896  );
897  } else {
898  printf(" Size: %lu.%lu (%lu) Tb\n", (ULONG)(max_lba/2048/1024/1024),
899  (ULONG)((max_lba/2048/1024)%1024)/10,
900  (ULONG)(max_lba*512/1000/1000/1000)
901  );
902  }
903  }
904  len = 0;
905  if((hKey2 = ata_get_bblist_regh(ident, DevSerial, TRUE))) {
906  if(RegQueryValueEx(hKey2, DevSerial, NULL, NULL, NULL, &len) == ERROR_SUCCESS) {
907  printf(" !!! Assigned bad-block list !!!\n");
908  }
909  RegCloseKey(hKey2);
910  }
911  } else {
912  switch(scsi_ident->DeviceType) {
914  if(scsi_ident->RemovableMedia) {
915  printf(" Floppy ");
916  } else {
917  printf(" Hard Drive ");
918  }
919  break;
921  printf(" Tape Drive ");
922  break;
923  case PRINTER_DEVICE:
924  printf(" Printer ");
925  break;
926  case PROCESSOR_DEVICE:
927  printf(" Processor ");
928  break;
930  printf(" WORM Drive ");
931  break;
933  printf(" CDROM Drive ");
934  break;
935  case SCANNER_DEVICE:
936  printf(" Scanner ");
937  break;
938  case OPTICAL_DEVICE:
939  printf(" Optical Drive ");
940  break;
941  case MEDIUM_CHANGER:
942  printf(" Changer ");
943  break;
945  printf(" Comm. device ");
946  break;
947  }
948  printf("\n");
949  }
950  }
951  memcpy(&g_ident, ident, sizeof(IDENTIFY_DATA));
952  }
953 next_dev:
954  if (inquiryData->NextInquiryDataOffset == 0) {
955  break;
956  }
957 
958  inquiryData = (PSCSI_INQUIRY_DATA) (g_inquiry_buffer +
959  inquiryData->NextInquiryDataOffset);
960  }
961  }
962  if(!found) {
963  printf(" No device(s) found.\n");
964  return FALSE;
965  }
966 
967  return TRUE;
968 } // end ata_check_unit()
969 
970 BOOLEAN
972  int bus_id,
973  int print_info
974  )
975 {
976  char dev_name[64];
977  HANDLE h;
978  PADAPTERINFO AdapterInfo;
979  ULONG status;
980  ULONG returned;
982  PCI_SLOT_NUMBER slotData;
983  char mode_str[12];
984  ULONG len;
985 
986  sprintf(dev_name, "\\\\.\\Scsi%d:", bus_id);
987  h = ata_open_dev(dev_name);
988  if(!h)
989  return FALSE;
990  addr.Length = sizeof(addr);
991  addr.PortNumber = bus_id;
992 
993  len = sizeof(ADAPTERINFO)+sizeof(CHANINFO)*AHCI_MAX_PORT;
994  if(!g_AdapterInfo) {
995  AdapterInfo = (PADAPTERINFO)GlobalAlloc(GMEM_FIXED, len);
996  if(!AdapterInfo) {
997  ata_close_dev(h);
998  return FALSE;
999  }
1000  } else {
1001  AdapterInfo = g_AdapterInfo;
1002  }
1003  memset(AdapterInfo, 0, len);
1004 
1005  status = ata_send_ioctl(h, &addr, "-UNIATA-",
1007  AdapterInfo, len,
1008  AdapterInfo, len,
1009  &returned);
1010  if(status) {
1011  ata_mode_to_str(mode_str, AdapterInfo->MaxTransferMode);
1012  }
1013  printf("Scsi%d: %s %s\n", bus_id, status ? "[UniATA]" : "", status ? mode_str : "");
1014  if(print_info) {
1015  if(!status) {
1016  printf("Can't get adapter info\n");
1017  } else {
1018  if(AdapterInfo->AdapterInterfaceType == PCIBus) {
1019  slotData.u.AsULONG = AdapterInfo->slotNumber;
1020  printf(" PCI Bus/Dev/Func: %lu/%lu/%lu%s\n",
1021  AdapterInfo->SystemIoBusNumber, slotData.u.bits.DeviceNumber, slotData.u.bits.FunctionNumber,
1022  AdapterInfo->AdapterInterfaceType == AdapterInfo->OrigAdapterInterfaceType ? "" : " (ISA-Bridged)");
1023  printf(" VendorId/DevId/Rev: %#04x/%#04x/%#02x\n",
1024  (USHORT)(AdapterInfo->DevID >> 16),
1025  (USHORT)(AdapterInfo->DevID & 0xffff),
1026  (UCHAR)(AdapterInfo->RevID));
1027  if(AdapterInfo->DeviceName[0]) {
1028  printf(" Name: %s\n", AdapterInfo->DeviceName);
1029  }
1030  } else
1031  if(AdapterInfo->AdapterInterfaceType == Isa) {
1032  printf(" ISA Bus\n");
1033  }
1034  printf(" IRQ: %ld\n", AdapterInfo->BusInterruptLevel);
1035  }
1036  }
1037  ata_close_dev(h);
1038  //GlobalFree(AdapterInfo);
1039  g_AdapterInfo = AdapterInfo;
1040  return status ? TRUE : FALSE;
1041 } // end ata_adapter_info()
1042 
1043 int
1045  HANDLE h, // handle to ScsiXXX:
1046  PIO_SCSI_CAPABILITIES capabilities
1047  )
1048 {
1049  ULONG status;
1050  ULONG returned;
1051 
1052  status = DeviceIoControl(h,
1054  NULL,
1055  0,
1056  capabilities,
1057  sizeof(IO_SCSI_CAPABILITIES),
1058  &returned,
1059  FALSE);
1060  return status;
1061 } // end ata_check_controller()
1062 
1063 BOOLEAN
1065  int bus_id,
1066  int dev_id
1067  )
1068 {
1069  char dev_name[64];
1070  HANDLE h;
1071  //BOOLEAN uniata_driven;
1072 
1073  if(bus_id == -1) {
1074  for(bus_id=0; TRUE; bus_id++) {
1075  if(!ata_list(bus_id, dev_id))
1076  break;
1077  }
1078  return TRUE;
1079  }
1080  /*uniata_driven =*/ ata_adapter_info(bus_id, g_adapter_info);
1081  sprintf(dev_name, "\\\\.\\Scsi%d:", bus_id);
1082  h = ata_open_dev(dev_name);
1083  if(!h)
1084  return FALSE;
1085  if(dev_id == -1) {
1086  ata_check_controller(h, &g_capabilities);
1087  ata_check_unit(h, -1);
1088  ata_close_dev(h);
1089  return TRUE;
1090  }
1091  ata_check_unit(h, dev_id | (bus_id << 24));
1092  ata_close_dev(h);
1093  return TRUE;
1094 } // end ata_list()
1095 
1096 BOOLEAN
1098  int bus_id,
1099  int dev_id,
1100  int mode
1101  )
1102 {
1103  char dev_name[64];
1104  HANDLE h;
1105  SETTRANSFERMODE IoMode;
1106  ULONG status;
1107  ULONG returned;
1109 
1110  if(dev_id == -1) {
1111  return FALSE;
1112  }
1113  sprintf(dev_name, "\\\\.\\Scsi%d:", bus_id);
1114  h = ata_open_dev(dev_name);
1115  if(!h)
1116  return FALSE;
1117  addr.Length = sizeof(addr);
1118  addr.PortNumber = bus_id;
1119  addr.PathId = (UCHAR)(dev_id >> 16);
1120  addr.TargetId = (UCHAR)(dev_id >> 8);
1121  addr.Lun = (UCHAR)(dev_id);
1122 
1123  IoMode.MaxMode = mode;
1124  IoMode.ApplyImmediately = FALSE;
1125 // IoMode.ApplyImmediately = TRUE;
1126  IoMode.OrigMode = mode;
1127 
1128  status = ata_send_ioctl(h, &addr, "-UNIATA-",
1130  &IoMode, sizeof(IoMode),
1131  NULL, 0,
1132  &returned);
1133  if(!status) {
1134  printf("Can't apply specified transfer mode\n");
1135  } else {
1136  ata_mode_to_str(dev_name, mode);
1137  printf("Transfer rate switched to %s\n", dev_name);
1138  }
1139  ata_close_dev(h);
1140  return status ? TRUE : FALSE;
1141 } // end ata_mode()
1142 
1143 BOOLEAN
1145  int bus_id,
1146  int dev_id
1147  )
1148 {
1149  char dev_name[64];
1150  HANDLE h;
1151  ULONG status;
1152  ULONG returned;
1154 
1155  if(dev_id == -1) {
1156  return FALSE;
1157  }
1158  sprintf(dev_name, "\\\\.\\Scsi%d:", bus_id);
1159  h = ata_open_dev(dev_name);
1160  if(!h)
1161  return FALSE;
1162  addr.Length = sizeof(addr);
1163  addr.PortNumber = bus_id;
1164  addr.PathId = (UCHAR)(dev_id >> 16);
1165  addr.TargetId = (UCHAR)(dev_id >> 8);
1166  addr.Lun = (UCHAR)(dev_id);
1167 
1168  if(addr.TargetId == 0x7f && addr.Lun == 0x7f) {
1169  addr.TargetId = (UCHAR)0xff;
1170  addr.Lun = 0;
1171  printf("Resetting channel...\n");
1172  } else {
1173  printf("Resetting device...\n");
1174  }
1175 
1176  status = ata_send_ioctl(h, &addr, "-UNIATA-",
1178  NULL, 0,
1179  NULL, 0,
1180  &returned);
1181  if(!status) {
1182  printf("Reset failed\n");
1183  } else {
1184  printf("Channel reset done\n");
1185  }
1186  ata_close_dev(h);
1187  return TRUE;
1188 } // end ata_reset()
1189 
1190 BOOLEAN
1192  int bus_id,
1193  int dev_id,
1194  int lock,
1195  int persistent_hide,
1196  int power_mode
1197  )
1198 {
1199  char dev_name[64];
1200  HANDLE h;
1201  ULONG status;
1202  ULONG returned;
1204  ADDREMOVEDEV to;
1205 
1206  if(dev_id == -1) {
1207  return FALSE;
1208  }
1209 
1210  if(power_mode) {
1211  ata_power_mode(bus_id, dev_id, power_mode);
1212  }
1213 
1214  if(lock < 0) {
1216  }
1217  sprintf(dev_name, "\\\\.\\Scsi%d:", bus_id);
1218  h = ata_open_dev(dev_name);
1219  if(!h)
1220  return FALSE;
1221  addr.Length = sizeof(addr);
1222  addr.PortNumber = bus_id;
1223  addr.PathId = (UCHAR)(dev_id >> 16);
1224  addr.TargetId = (UCHAR)(dev_id >> 8);
1225  addr.Lun = (UCHAR)(dev_id);
1226 
1228  to.Flags = persistent_hide ? UNIATA_REMOVE_FLAGS_HIDE : 0;
1229 
1230  printf("Deleting device.\n");
1231  if(lock) {
1232  printf("ATTENTION: you have %d seconds to disconnect cable\n", lock);
1233  }
1234  status = ata_send_ioctl(h, &addr, "-UNIATA-",
1236  &to, sizeof(to),
1237  NULL, 0,
1238  &returned);
1239  if(!status) {
1240  printf("Delete failed\n");
1241  } else {
1242  printf("Device is detached\n");
1243  }
1244  ata_close_dev(h);
1245  return status ? TRUE : FALSE;
1246 } // end ata_hide()
1247 
1248 BOOLEAN
1250  int bus_id,
1251  int dev_id,
1252  int lock,
1253  int unhide
1254  )
1255 {
1256  char dev_name[64];
1257  HANDLE h;
1258  ULONG status;
1259  ULONG returned;
1261  ADDREMOVEDEV to;
1262 
1263  if(dev_id == -1) {
1264  return FALSE;
1265  }
1266  if(lock < 0) {
1268  }
1269  sprintf(dev_name, "\\\\.\\Scsi%d:", bus_id);
1270  h = ata_open_dev(dev_name);
1271  if(!h)
1272  return FALSE;
1273 
1274  if((UCHAR)(dev_id) != 0xff &&
1275  (UCHAR)(dev_id >> 8) != 0xff) {
1276 
1277  addr.Length = sizeof(addr);
1278  addr.PortNumber = bus_id;
1279  addr.PathId = (UCHAR)(dev_id >> 16);
1280  addr.TargetId = 0;
1281  addr.Lun = 0;
1282 
1284  to.Flags = unhide ? UNIATA_ADD_FLAGS_UNHIDE : 0;
1285 
1286  printf("Scanning bus for new devices.\n");
1287  if(lock) {
1288  printf("You have %d seconds to connect device.\n", lock);
1289  }
1290  status = ata_send_ioctl(h, &addr, "-UNIATA-",
1292  &to, sizeof(to),
1293  NULL, 0,
1294  &returned);
1295  } else {
1296  status = DeviceIoControl(h,
1298  NULL, 0,
1299  NULL, 0,
1300  &returned,
1301  FALSE);
1302  }
1303  ata_close_dev(h);
1304  return status ? TRUE : FALSE;
1305 } // end ata_scan()
1306 
1307 CHAR*
1309  CHAR *string,
1310  int count,
1311  HANDLE stream
1312  )
1313 {
1314  CHAR *pointer = string;
1315  ULONG read_bytes;
1316 
1317  CHAR *retval = string;
1318  int ch = 0;
1319 
1320  if (count <= 0)
1321  return(NULL);
1322 
1323  while (--count)
1324  {
1325  if(!ReadFile(stream, &ch, 1, &read_bytes, NULL) ||
1326  !read_bytes)
1327  {
1328  if (pointer == string) {
1329  retval=NULL;
1330  goto done;
1331  }
1332  break;
1333  }
1334 
1335  if ((*pointer++ = (CHAR)ch) == '\n') {
1336  break;
1337  }
1338  }
1339 
1340  *pointer = '\0';
1341 
1342 /* Common return */
1343 done:
1344  return(retval);
1345 } // end _fgets()
1346 
1347 BOOLEAN
1349  int bus_id,
1350  int dev_id,
1351  int list_bb
1352  )
1353 {
1354  char dev_name[64];
1355  char tmp[64];
1356  char DevSerial[128];
1357  HANDLE h = NULL;
1358  HANDLE hf = NULL;
1359  ULONG status;
1360  ULONG returned;
1362  ULONG len;
1363  ULONG Length;
1364  BOOLEAN retval = FALSE;
1365  HKEY hKey2 = NULL;
1366  char* bblist = NULL;
1367  LONGLONG tmp_bb_lba;
1368  LONGLONG tmp_bb_len;
1369  char BB_Msg[256];
1370  int radix=gRadix;
1371  int i, j;
1372  ULONG b;
1373 
1374  if(dev_id == -1) {
1375  printf("\nERROR: Target device/bus ID must be specified\n\n");
1376  print_help();
1377  return FALSE;
1378  }
1379  if(((dev_id >> 16) & 0xff) == 0xff) {
1380  printf("\nERROR: Target device bus number (channel) must be specified with b:<bus id>\n\n");
1381  print_help();
1382  return FALSE;
1383  }
1384  if(((dev_id >> 8) & 0xff) == 0xff) {
1385  printf("\nERROR: Target device ID must be specified with d:<device id>\n\n");
1386  print_help();
1387  return FALSE;
1388  }
1389  sprintf(dev_name, "\\\\.\\Scsi%d:", bus_id);
1390  h = ata_open_dev(dev_name);
1391  if(!h) {
1392  if(bus_id == -1) {
1393  printf("Controller number must be specified\n");
1394  } else {
1395  printf("Can't open Controller %d\n", bus_id);
1396  }
1397  return FALSE;
1398  }
1399 
1400  if(list_bb == 0) {
1401  hf = ata_open_file(g_bb_list, FALSE);
1402  if(!hf) {
1403  printf("Can't open bad block list file:\n %s\n", g_bb_list);
1404  ata_close_dev(h);
1405  return FALSE;
1406  }
1407 
1408  len = GetFileSize(hf, NULL);
1409  if(!len || len == INVALID_FILE_SIZE)
1410  goto exit;
1411  bblist = (char*)GlobalAlloc(GMEM_FIXED, len*8);
1412  }
1413 
1414  if(!ata_check_unit(h, dev_id | (bus_id << 24))) {
1415  goto exit;
1416  }
1417 
1418  hKey2 = ata_get_bblist_regh(&g_ident, DevSerial, list_bb==1);
1419  if(!hKey2) {
1420  printf("Can't open registry key:\n HKLM\\SYSTEM\\CurrentControlSet\\Services\\UniATA\\Parameters\\BadBlocks\n");
1421  goto exit;
1422  }
1423 
1424  if(list_bb == -1) {
1425  if(RegDeleteValue(hKey2, DevSerial) != ERROR_SUCCESS) {
1426  printf("Can't delete registry value:\n %s\n", DevSerial);
1427  goto exit;
1428  }
1429 
1430  addr.PortNumber = bus_id;
1431  addr.PathId = (UCHAR)(dev_id >> 16);
1432  addr.TargetId = (UCHAR)(dev_id >> 8);
1433  addr.Lun = (UCHAR)(dev_id);
1434 
1435  status = ata_send_ioctl(h, &addr, "-UNIATA-",
1437  NULL, 0,
1438  NULL, 0,
1439  &returned);
1440  if(!status) {
1441  printf("Bad block list shall be cleared after reboot.\n");
1442  } else {
1443  printf("Bad block list cleared\n");
1444  }
1445  } else
1446  if(list_bb == 0) {
1447  LONGLONG* pData = ((LONGLONG*)bblist);
1448  char a;
1449  int k, k0;
1450  Length=0;
1451  i=0;
1452  j=0;
1453  k=0;
1454  while(_fgets(BB_Msg, sizeof(BB_Msg), hf)) {
1455  j++;
1456  BB_Msg[sizeof(BB_Msg)-1] = 0;
1457  k=0;
1458  while((a = BB_Msg[k])) {
1459  if(a == ' ' || a == '\t' || a == '\r') {
1460  k++;
1461  continue;
1462  }
1463  break;
1464  }
1465  if(!a || a == ';' || a == '#') {
1466  continue;
1467  }
1468  if(!strncmp(BB_Msg+k, "hex:", 4)) {
1469  radix=16;
1470  continue;
1471  }
1472  if(!strncmp(BB_Msg+k, "dec:", 4)) {
1473  radix=10;
1474  continue;
1475  }
1476  k0 = k;
1477  while((a = BB_Msg[k])) {
1478  if(a == ' ' || a == '\t' || a == '\r') {
1479  BB_Msg[k] = '\t';
1480  }
1481  k++;
1482  if(a == ';' || a == '#') {
1483  break;
1484  }
1485  if(a >= '0' && a <= '9') {
1486  continue;
1487  }
1488  if(radix == 16 && ((a >= 'A' && a <= 'F') || (a >= 'a' && a <= 'f'))) {
1489  continue;
1490  }
1491  printf("Bad input BB list file:\n %s\n", g_bb_list);
1492  printf("Illegal character '%1.1s' in line %d:\n%s\n", BB_Msg+k-1, j, BB_Msg);
1493  k0=-1;
1494  break;
1495  }
1496  if(k0 == -1) {
1497  continue;
1498  }
1499  k = k0;
1500  if(radix == 10) {
1501  b = sscanf(BB_Msg+k, "%I64u\t%I64u", &tmp_bb_lba, &tmp_bb_len);
1502  } else {
1503  b = sscanf(BB_Msg+k, "%I64x\t%I64x", &tmp_bb_lba, &tmp_bb_len);
1504  }
1505  if(b == 1) {
1506  tmp_bb_len = 1;
1507  } else
1508  if(b != 2) {
1509  printf("Bad input BB list file:\n %s\n", g_bb_list);
1510  printf("Can't parse line %d:\n%s\n", j, BB_Msg);
1511  continue;
1512  }
1513  if(!tmp_bb_len) {
1514  printf("Bad input BB list file:\n %s\n", g_bb_list);
1515  printf("BlockCount evaluated to 0 in line %d:\n%s\n", j, BB_Msg);
1516  continue;
1517  }
1518  if(tmp_bb_lba < 0) {
1519  printf("Bad input BB list file:\n %s\n", g_bb_list);
1520  printf("Start LBA evaluated to negative in line %d:\n%s\n", j, BB_Msg);
1521  continue;
1522  }
1523  if(tmp_bb_len < 0) {
1524  printf("Bad input BB list file:\n %s\n", g_bb_list);
1525  printf("BlockCount evaluated to negative in line %d:\n%s\n", j, BB_Msg);
1526  continue;
1527  }
1528 
1529  if(i &&
1530  (pData[(i-1)*2+1] == tmp_bb_lba)) {
1531  pData[(i-1)*2+1]+=tmp_bb_len;
1532  } else {
1533  pData[i*2+0]=tmp_bb_lba;
1534  pData[i*2+1]=tmp_bb_lba+tmp_bb_len;
1535  i++;
1536  Length += sizeof(LONGLONG)*2;
1537  }
1538  }
1539 
1540  if(RegSetValueEx(hKey2, DevSerial, NULL, REG_BINARY, (const UCHAR*)bblist, Length) != ERROR_SUCCESS) {
1541  printf("Can't set registry value:\n %s\n", DevSerial);
1542  goto exit;
1543  }
1544 /*
1545  addr.PortNumber = bus_id;
1546  addr.PathId = (UCHAR)(dev_id >> 16);
1547  addr.TargetId = (UCHAR)(dev_id >> 8);
1548  addr.Lun = (UCHAR)(dev_id);
1549 
1550  status = ata_send_ioctl(h, &addr, "-UNIATA-",
1551  IOCTL_SCSI_MINIPORT_UNIATA_SETBB,
1552  NULL, 0,
1553  NULL, 0,
1554  &returned);
1555 */
1556  printf("Bad block list shall be applied after reboot\n");
1557  } else {
1558  len = 0;
1559  returned = RegQueryValueEx(hKey2, DevSerial, NULL, NULL, NULL, &len);
1560  if(returned == 2) {
1561  printf("No bad block list assigned\n");
1562  goto exit;
1563  } else
1564  if(returned != ERROR_SUCCESS) {
1565  printf("Can't get registry value:\n %s\n", DevSerial);
1566  goto exit;
1567  }
1568 
1569  hf = ata_open_file(g_bb_list, TRUE);
1570  if(!hf) {
1571  printf("Can't create bad block list file:\n %s\n", g_bb_list);
1572  goto exit;
1573  }
1574 
1575  bblist = (char*)GlobalAlloc(GMEM_FIXED, len);
1576  if(RegQueryValueEx(hKey2, DevSerial, NULL, NULL, (UCHAR*)bblist, &len) != ERROR_SUCCESS) {
1577  printf("Can't get registry value:\n %s\n", DevSerial);
1578  goto exit;
1579  }
1580  if(g_bb_list) {
1581  for (j = 0; j < 20; j += 2) {
1582  MOV_DW_SWP(tmp[j], ((PUCHAR)(&g_ident.ModelNumber))[j]);
1583  }
1584  b = sprintf(BB_Msg, "#model: %20.20s\n", tmp);
1585  WriteFile(hf, BB_Msg, b, &returned, NULL);
1586  for (j = 0; j < 4; j += 2) {
1587  MOV_DW_SWP(tmp[j], ((PUCHAR)(&g_ident.FirmwareRevision))[j]);
1588  }
1589  b = sprintf(BB_Msg, "#rev: %4.4s\n", tmp);
1590  WriteFile(hf, BB_Msg, b, &returned, NULL);
1591  for (j = 0; j < 20; j += 2) {
1592  MOV_DW_SWP(tmp[j], ((PUCHAR)(&g_ident.SerialNumber))[j]);
1593  }
1594  b = sprintf(BB_Msg, "#s/n: %20.20s\n", tmp);
1595  WriteFile(hf, BB_Msg, b, &returned, NULL);
1596  b = sprintf(BB_Msg, "#%s\n", DevSerial);
1597  WriteFile(hf, BB_Msg, b, &returned, NULL);
1598  b = sprintf(BB_Msg, "#Starting LBA\tNum. of Blocks\n");
1599  WriteFile(hf, BB_Msg, b, &returned, NULL);
1600  b = sprintf(BB_Msg, "hex:\n");
1601  WriteFile(hf, BB_Msg, b, &returned, NULL);
1602  } else {
1603  b = sprintf(BB_Msg, "Starting LBA\tNum. of Blocks (HEX)\n");
1604  WriteFile(hf, BB_Msg, b, &returned, NULL);
1605  }
1606  i = 0;
1607  while(len >= sizeof(LONGLONG)*2) {
1608  tmp_bb_lba = ((LONGLONG*)bblist)[i*2+0];
1609  tmp_bb_len = ((LONGLONG*)bblist)[i*2+1] - tmp_bb_lba;
1610  b = sprintf(BB_Msg, "%I64u\t%I64u\n", tmp_bb_lba, tmp_bb_len);
1611  WriteFile(hf, BB_Msg, b, &returned, NULL);
1612  i++;
1613  len -= sizeof(LONGLONG)*2;
1614  }
1615  }
1616  retval = TRUE;
1617 exit:
1618  if(hKey2)
1619  RegCloseKey(hKey2);
1620  if(bblist) {
1621  GlobalFree(bblist);
1622  }
1623  ata_close_dev(hf);
1624  ata_close_dev(h);
1625  return retval;
1626 } // end ata_bblk()
1627 
1628 BOOLEAN
1630  int bus_id,
1631  int dev_id,
1632  int power_mode
1633  )
1634 {
1635  char dev_name[64];
1636  HANDLE h;
1637  ULONG status;
1638  ULONG returned;
1640  CDB cdb;
1641  SENSE_DATA senseData;
1642 
1643  if(dev_id == -1) {
1644  return FALSE;
1645  }
1646  if(!power_mode) {
1647  return TRUE;
1648  }
1649 
1650  sprintf(dev_name, "\\\\.\\Scsi%d:", bus_id);
1651  h = ata_open_dev(dev_name);
1652  if(!h)
1653  return FALSE;
1654  addr.PortNumber = bus_id;
1655  addr.PathId = (UCHAR)(dev_id >> 16);
1656  addr.TargetId = (UCHAR)(dev_id >> 8);
1657  addr.Lun = (UCHAR)(dev_id);
1658 
1659  memset(&cdb, 0, sizeof(cdb));
1660  cdb.START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
1661  cdb.START_STOP.Immediate = 1;
1662  cdb.START_STOP.PowerConditions = power_mode;
1663  cdb.START_STOP.Start = (power_mode != StartStop_Power_Sleep);
1664 
1665  printf("Changing power state to ...\n");
1666 
1667  status = ata_send_scsi(h, &addr, &cdb, 6,
1668  NULL, 0, FALSE,
1669  &senseData, &returned);
1670  ata_close_dev(h);
1671  return status ? TRUE : FALSE;
1672 } // end ata_power_mode()
1673 
1674 int
1676  char a
1677  )
1678 {
1679  if(a >= '0' && a <= '9')
1680  return a-'0';
1681  return -1;
1682 }
1683 
1684 int
1686  int argc,
1687  char* argv[]
1688  )
1689 {
1690  //ULONG Flags = 0;
1691  int i, j;
1692  char a;
1693  int bus_id = -1;
1694  int dev_id = -1;
1695  int cmd = 0;
1696  int lock = -1;
1697  int b_dev=-1, d_dev=-1, l_dev=0;
1698  int mode=-1;
1699  int list_bb=0;
1700  int persistent_hide=0;
1701  int power_mode=StartStop_Power_NoChg;
1702 
1703  printf("Console ATA control utility for Windows NT3.51/NT4/2000/XP/2003\n"
1704  "Version 0." UNIATA_VER_STR ", Copyright (c) Alexander A. Telyatnikov, 2003-2012\n"
1705  "Home site: http://alter.org.ua\n");
1706 
1707  for(i=1; i<argc; i++) {
1708  if(!argv[i])
1709  continue;
1710  if((a = argv[i][0]) != '-') {
1711  for(j=0; (a = argv[i][j]); j++) {
1712  switch(a) {
1713  case 'a' :
1714  case 's' :
1715  case 'c' :
1716  j++;
1717  bus_id = ata_num_to_x_dev(argv[i][j]);
1718  break;
1719  case 'b' :
1720  j++;
1721  b_dev = ata_num_to_x_dev(argv[i][j]);
1722  break;
1723  case 'd' :
1724  j++;
1725  d_dev = ata_num_to_x_dev(argv[i][j]);
1726  break;
1727  case 'l' :
1728  j++;
1729  l_dev = ata_num_to_x_dev(argv[i][j]);
1730  break;
1731  case ':' :
1732  break;
1733  default:
1734  print_help();
1735  }
1736  }
1737  continue;
1738  }
1739  j=1;
1740  while(argv[i] && (a = argv[i][j]) && (a != ' ') && (a != '\t')) {
1741  switch(a) {
1742  case 'l' :
1743  if(cmd || lock>0) {
1744  print_help();
1745  }
1746  cmd = CMD_ATA_LIST;
1747  break;
1748  case 'x' :
1749  g_extended = 1;
1750  break;
1751  case 'a' :
1752  g_adapter_info = 1;
1753  break;
1754  case 'S' :
1755  persistent_hide = 1;
1756  case 's' :
1757  if(cmd || lock>0) {
1758  print_help();
1759  }
1760  cmd = CMD_ATA_FIND;
1761  d_dev = 0;
1762  break;
1763  case 'H' :
1764  persistent_hide = 1;
1765  case 'h' :
1766  if(cmd) {
1767  print_help();
1768  }
1769  cmd = CMD_ATA_HIDE;
1770  d_dev = 0;
1771  break;
1772  case 'm' :
1773  if(cmd) {
1774  print_help();
1775  }
1776  cmd = CMD_ATA_MODE;
1777  i++;
1778  if(!argv[i]) {
1779  print_help();
1780  }
1781  mode = ata_str_to_mode(argv[i]);
1782  if(mode == -1) {
1783  i--;
1784  } else {
1785  j = strlen(argv[i])-1;
1786  }
1787  break;
1788  case 'r' :
1789  if(cmd) {
1790  print_help();
1791  }
1792  cmd = CMD_ATA_RESET;
1793  break;
1794  case 'b' :
1795  if(cmd) {
1796  print_help();
1797  }
1798  switch(argv[i][j+1]) {
1799  case 'l':
1800  list_bb = 1;
1801  break;
1802  case 'a':
1803  list_bb = 0;
1804  break;
1805  case 'r':
1806  list_bb = -1;
1807  break;
1808  default:
1809  j--;
1810  }
1811  j++;
1812  cmd = CMD_ATA_BBLK;
1813  break;
1814  case 'f' :
1815  if(cmd != CMD_ATA_BBLK) {
1816  print_help();
1817  }
1818  i++;
1819  if(!argv[i]) {
1820  print_help();
1821  }
1822  g_bb_list=argv[i];
1823  j = strlen(argv[i])-1;
1824  break;
1825  case 'p' :
1826  if(cmd && (cmd != CMD_ATA_FIND) && (cmd != CMD_ATA_HIDE)) {
1827  print_help();
1828  }
1829  switch(argv[i][j+1]) {
1830  case '0':
1831  case 'a':
1832  // do nothing
1833  break;
1834  case '1':
1835  case 'i':
1836  power_mode = StartStop_Power_Idle;
1837  break;
1838  case '2':
1839  case 's':
1840  power_mode = StartStop_Power_Standby;
1841  break;
1842  case '3':
1843  case 'p':
1844  power_mode = StartStop_Power_Sleep;
1845  break;
1846  default:
1847  j--;
1848  }
1849  j++;
1850  if(power_mode && !cmd) {
1851  cmd = CMD_ATA_POWER;
1852  }
1853  break;
1854  case 'D' :
1855  power_mode = StartStop_Power_Sleep;
1856  if(cmd && (cmd != CMD_ATA_HIDE)) {
1857  print_help();
1858  }
1859  case 'd' :
1860  if(cmd && (cmd != CMD_ATA_FIND) && (cmd != CMD_ATA_HIDE) && (cmd != CMD_ATA_POWER)) {
1861  print_help();
1862  }
1863  if(!cmd) {
1864  cmd = CMD_ATA_HIDE;
1865  }
1866  i++;
1867  if(!argv[i]) {
1868  print_help();
1869  }
1870  if(!sscanf(argv[i], "%d", &lock)) {
1872  i--;
1873  }
1874  j = strlen(argv[i])-1;
1875  break;
1876  case 'n' :
1877  if(cmd != CMD_ATA_BBLK) {
1878  print_help();
1879  }
1880  i++;
1881  if(!argv[i]) {
1882  print_help();
1883  }
1884  if(!strcmp(argv[i], "hex") ||
1885  !strcmp(argv[i], "16")) {
1886  gRadix = 16;
1887  } else
1888  if(!strcmp(argv[i], "dec") ||
1889  !strcmp(argv[i], "10")) {
1890  gRadix = 10;
1891  } else {
1892  print_help();
1893  }
1894  j = strlen(argv[i])-1;
1895  break;
1896  case '?' :
1897  default:
1898  print_help();
1899  }
1900  j++;
1901  }
1902  }
1903 
1904  if(g_adapter_info && !cmd) {
1905  cmd = CMD_ATA_LIST;
1906  b_dev = 127;
1907  d_dev = 127;
1908  l_dev = 127;
1909  } else
1910  if((d_dev == -1) && (b_dev != -1)) {
1911  d_dev = 127;
1912  l_dev = 127;
1913  }
1914 
1915  if((d_dev != -1) && (b_dev != -1)) {
1916  dev_id = (b_dev << 16) | (d_dev << 8) | l_dev;
1917  }
1918  if(cmd == CMD_ATA_LIST) {
1919  ata_list(bus_id, dev_id);
1920  } else
1921  if(cmd == CMD_ATA_MODE) {
1922  ata_mode(bus_id, dev_id, mode);
1923  } else
1924  if(cmd == CMD_ATA_RESET) {
1925  ata_reset(bus_id, dev_id);
1926  } else
1927  if(cmd == CMD_ATA_FIND) {
1928  ata_scan(bus_id, dev_id, lock, persistent_hide);
1929  } else
1930  if(cmd == CMD_ATA_HIDE) {
1931  ata_hide(bus_id, dev_id, lock, persistent_hide, power_mode);
1932  } else
1933  if(cmd == CMD_ATA_BBLK) {
1934  ata_bblk(bus_id, dev_id, list_bb);
1935  } else
1936  if(cmd == CMD_ATA_POWER) {
1937  ata_power_mode(bus_id, dev_id, power_mode);
1938  } else {
1939  print_help();
1940  }
1941  exit(0);
1942 }
1943 
UCHAR PathId
Definition: scsi_port.h:151
#define RegQueryValueEx
Definition: winreg.h:524
signed char * PCHAR
Definition: retypes.h:7
UCHAR PortNumber
Definition: scsi_port.h:150
#define ATA_PIO0
Definition: atapi.h:308
static int argc
Definition: ServiceArgs.c:12
#define IN
Definition: typedefs.h:38
ULONG NumberChannels
Definition: uata_ctl.h:145
#define IOCTL_SCSI_MINIPORT_UNIATA_RESET_DEVICE
Definition: uata_ctl.h:67
#define max(a, b)
Definition: svc.c:63
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
BOOLEAN ata_hide(int bus_id, int dev_id, int lock, int persistent_hide, int power_mode)
Definition: atactl.cpp:1191
#define TRUE
Definition: types.h:120
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
BOOLEAN ata_adapter_info(int bus_id, int print_info)
Definition: atactl.cpp:971
#define CloseHandle
Definition: compat.h:398
int gRadix
Definition: atactl.cpp:42
__inline LONG ata_cur_mode_from_ident(PIDENTIFY_DATA ident, BOOLEAN Active)
Definition: atapi.h:1649
#define IOCTL_SCSI_MINIPORT_UNIATA_ADAPTER_INFO
Definition: uata_ctl.h:64
UCHAR ProductRevisionLevel[4]
Definition: cdrw_hw.h:1134
#define ATAPI_TYPE_DIRECT
Definition: atapi.h:621
#define UNIATA_COMM_PORT_VENDOR_STR
Definition: uata_ctl.h:56
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
struct _SENDCMDOUTPARAMS * PSENDCMDOUTPARAMS
void ata_mode_to_str(char *str, int mode)
Definition: atactl.cpp:399
#define ATA_PIO
Definition: atapi.h:305
#define CMD_ATA_POWER
Definition: atactl.cpp:136
rwlock_t lock
Definition: tcpcore.h:1163
#define ERROR_SUCCESS
Definition: deptool.c:10
int ata_check_unit(HANDLE h, int dev_id)
Definition: atactl.cpp:609
#define CMD_ATA_MODE
Definition: atactl.cpp:133
ULONG EncodeVendorStr(OUT char *Buffer, IN PUCHAR Str, IN ULONG Length, IN ULONG Xorer)
Definition: atactl.cpp:524
#define CMD_ATA_HIDE
Definition: atactl.cpp:132
BOOLEAN ata_scan(int bus_id, int dev_id, int lock, int unhide)
Definition: atactl.cpp:1249
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ATA_UDMA1
Definition: atapi.h:328
HKEY ata_get_bblist_regh(IN PIDENTIFY_DATA ident, OUT char *DevSerial, BOOLEAN read_only)
Definition: atactl.cpp:563
#define IOCTL_SCSI_MINIPORT
Definition: scsi_port.h:50
#define REG_BINARY
Definition: nt_native.h:1496
Definition: ftp_var.h:139
GLsizei const GLvoid * pointer
Definition: glext.h:5848
int ata_num_to_x_dev(char a)
Definition: atactl.cpp:1675
#define KEY_READ
Definition: nt_native.h:1023
struct _IDENTIFY_DATA::@1003 FeaturesSupport
int main(int argc, char *argv[])
Definition: atactl.cpp:1685
#define CMD_ATA_BBLK
Definition: atactl.cpp:135
GLuint GLuint GLsizei count
Definition: gl.h:1545
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
int g_adapter_info
Definition: atactl.cpp:40
#define CMD_ATA_LIST
Definition: atactl.cpp:130
Definition: cdrw_hw.h:28
int ata_check_controller(HANDLE h, PIO_SCSI_CAPABILITIES capabilities)
Definition: atactl.cpp:1044
ULONG Length
Definition: scsi_port.h:149
#define StartStop_Power_Standby
Definition: scsi.h:408
#define ATA_PIO_NRDY
Definition: atapi.h:306
UCHAR DeviceType
Definition: atapi.h:620
#define ATA_UDMA0
Definition: atapi.h:327
#define ATAPI_TYPE_CDROM
Definition: atapi.h:623
struct _SENDCMDOUTPARAMS SENDCMDOUTPARAMS
#define WRITE_ONCE_READ_MULTIPLE_DEVICE
Definition: cdrw_hw.h:1148
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
const char * dev_name(int device)
Definition: wave.c:211
#define ATA_SA600
Definition: atapi.h:338
#define IOCTL_SCSI_MINIPORT_UNIATA_RESETBB
Definition: uata_ctl.h:66
#define ATA_UDMA4
Definition: atapi.h:331
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:152
#define ATAPI_ID_CMD
Definition: helper.h:19
static BOOL read_bytes(parse_buffer *buf, LPVOID data, DWORD size)
Definition: parsing.c:169
ULONG DataBufferOffset
Definition: scsi_port.h:71
#define ATA_SA300
Definition: atapi.h:337
#define DEFAULT_REMOVAL_LOCK_TIMEOUT
Definition: atactl.cpp:18
struct _INQUIRYDATA * PINQUIRYDATA
ULONG AdapterInterfaceType
Definition: uata_ctl.h:152
ULONG SenseInfoOffset
Definition: scsi_port.h:72
#define INVALID_FILE_SIZE
Definition: winbase.h:529
#define RegCreateKey
Definition: winreg.h:500
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
ULONG NextInquiryDataOffset
Definition: scsi_port.h:120
#define SCANNER_DEVICE
Definition: cdrw_hw.h:1150
UCHAR VendorId[8]
Definition: cdrw_hw.h:1132
BOOLEAN ata_list(int bus_id, int dev_id)
Definition: atactl.cpp:1064
CHAR DeviceName[64]
Definition: uata_ctl.h:136
ULONG slotNumber
Definition: uata_ctl.h:120
ULONG CurrentMode
Definition: uata_ctl.h:90
#define _stricmp
Definition: cat.c:22
UCHAR TargetId
Definition: scsi_port.h:152
UCHAR Removable
Definition: atapi.h:618
void ata_close_dev(HANDLE h)
Definition: atactl.cpp:235
static char ** argv
Definition: ServiceArgs.c:11
#define PROCESSOR_DEVICE
Definition: cdrw_hw.h:1147
#define FILE_SHARE_READ
Definition: compat.h:125
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
ULONG UserAddressableSectors
Definition: atapi.h:223
#define MOV_DW_SWP(a, b)
Definition: atactl.cpp:20
Definition: regsvr.c:103
SCSI_BUS_DATA BusData[1]
Definition: scsi_port.h:108
#define sprintf(buf, format,...)
Definition: sprintf.c:55
UCHAR Cdb[16]
Definition: scsi_port.h:73
#define IOCTL_SCSI_MINIPORT_UNIATA_FIND_DEVICES
Definition: uata_ctl.h:60
ULONG DataTransferLength
Definition: scsi_port.h:69
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define ATAPI_TYPE_OPTICAL
Definition: atapi.h:624
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define ATA_UDMA6
Definition: atapi.h:333
UCHAR g_inquiry_buffer[2048]
Definition: atactl.cpp:396
UCHAR SenseInfoLength
Definition: scsi_port.h:67
_In_ ULONG BufferLength
Definition: usbdlib.h:225
HANDLE ata_open_file(char *Name, BOOLEAN create)
Definition: atactl.cpp:202
#define UNIATA_VER_STR
Definition: uniata_ver.h:1
#define a
Definition: ke_i.h:78
#define SEQUENTIAL_ACCESS_DEVICE
Definition: cdrw_hw.h:1145
#define GENERIC_WRITE
Definition: nt_native.h:90
#define IOCTL_SCSI_MINIPORT_UNIATA_DELETE_DEVICE
Definition: uata_ctl.h:61
BOOLEAN ApplyImmediately
Definition: uata_ctl.h:83
struct _ADAPTERINFO ADAPTERINFO
HANDLE ata_open_dev(char *Name)
Definition: atactl.cpp:139
struct _SCSI_INQUIRY_DATA * PSCSI_INQUIRY_DATA
_Check_return_ _CRTIMP int __cdecl _memicmp(_In_reads_bytes_opt_(_Size) const void *_Buf1, _In_reads_bytes_opt_(_Size) const void *_Buf2, _In_ size_t _Size)
USHORT FirmwareRevision[4]
Definition: atapi.h:205
UCHAR RemovableMedia
Definition: cdrw_hw.h:1119
const WCHAR * str
unsigned char BOOLEAN
#define PRINTER_DEVICE
Definition: cdrw_hw.h:1146
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
struct _ADAPTERINFO * PADAPTERINFO
ULONG MaxTransferMode
Definition: uata_ctl.h:132
ULONG SystemIoBusNumber
Definition: uata_ctl.h:121
Definition: bufpool.h:45
int ata_send_scsi(HANDLE h, PSCSI_ADDRESS addr, PCDB cdb, UCHAR cdbLength, PVOID Buffer, ULONG BufferLength, BOOLEAN DataIn, PSENSE_DATA senseData, PULONG returned)
Definition: atactl.cpp:326
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
#define ATA_SA150
Definition: atapi.h:336
struct _CDB::_START_STOP START_STOP
ULONGLONG UserAddressableSectors48
Definition: atapi.h:854
ULONG InquiryDataOffset
Definition: scsi_port.h:100
#define STD_INPUT_HANDLE
Definition: winbase.h:264
IDENTIFY_DATA g_ident
Definition: atactl.cpp:606
struct _CHANINFO * PCHANINFO
#define SCSI_IOCTL_DATA_IN
Definition: scsi_port.h:175
#define OPEN_EXISTING
Definition: compat.h:426
#define b
Definition: ke_i.h:79
struct _IDENTIFY_DATA * PIDENTIFY_DATA
union _PCI_SLOT_NUMBER::@3627 u
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3993
char * g_bb_list
Definition: atactl.cpp:41
BOOLEAN ata_reset(int bus_id, int dev_id)
Definition: atactl.cpp:1144
ULONG BusInterruptLevel
Definition: uata_ctl.h:138
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
#define DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1144
struct _SCSI_PASS_THROUGH_WITH_BUFFERS * PSCSI_PASS_THROUGH_WITH_BUFFERS
int64_t LONGLONG
Definition: typedefs.h:66
#define IOCTL_SCSI_RESCAN_BUS
Definition: scsi_port.h:55
CONST CHAR * PCCH
Definition: ntbasedef.h:399
#define RegDeleteValue
Definition: winreg.h:508
#define ID_CMD
Definition: helper.h:20
struct _UNIATA_CTL * PUNIATA_CTL
IO_SCSI_CAPABILITIES g_capabilities
Definition: atactl.cpp:395
#define IDENT_MODE_ACTIVE
Definition: atapi.h:1645
USHORT SerialNumber[10]
Definition: atapi.h:201
IDEREGS irDriveRegs
Definition: helper.h:32
uint64_t ULONGLONG
Definition: typedefs.h:65
struct _PCI_SLOT_NUMBER::@3627::@3628 bits
UCHAR bCommandReg
Definition: helper.h:15
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define IOCTL_SCSI_MINIPORT_UNIATA_GET_MODE
Definition: uata_ctl.h:63
ULONG OrigMode
Definition: uata_ctl.h:82
int g_extended
Definition: atactl.cpp:39
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:481
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define READ_CONTROL
Definition: nt_native.h:58
BOOLEAN ata_mode(int bus_id, int dev_id, int mode)
Definition: atactl.cpp:1097
unsigned char UCHAR
Definition: xmlstorage.h:181
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
GLenum const GLvoid * addr
Definition: glext.h:9621
Definition: parse.h:22
#define GMEM_FIXED
Definition: winbase.h:290
#define ATA_WDMA0
Definition: atapi.h:322
BOOLEAN ata_power_mode(int bus_id, int dev_id, int power_mode)
Definition: atactl.cpp:1629
ULONG DevID
Definition: uata_ctl.h:118
#define CMD_ATA_FIND
Definition: atactl.cpp:131
ULONG WaitForPhysicalLink
Definition: uata_ctl.h:72
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
int ata_send_ioctl(HANDLE h, PSCSI_ADDRESS addr, PCCH Signature, ULONG Ioctl, PVOID inBuffer, ULONG inBufferLength, PVOID outBuffer, ULONG outBufferLength, PULONG returned)
Definition: atactl.cpp:243
UCHAR MaximumBlockTransfer
Definition: atapi.h:207
#define UNIATA_ADD_FLAGS_UNHIDE
Definition: uata_ctl.h:76
#define GENERIC_READ
Definition: compat.h:124
ULONG ChanHeaderLength
Definition: uata_ctl.h:153
#define STD_OUTPUT_HANDLE
Definition: winbase.h:265
#define AHCI_MAX_PORT
Definition: bsmaster.h:105
GLenum mode
Definition: glext.h:6217
UCHAR InquiryData[1]
Definition: scsi_port.h:121
char string[160]
Definition: util.h:11
BOOLEAN ChanHeaderLengthValid
Definition: uata_ctl.h:150
#define StartStop_Power_Idle
Definition: scsi.h:407
#define IOCTL_SCSI_PASS_THROUGH
Definition: scsi_port.h:49
UCHAR DeviceType
Definition: cdrw_hw.h:1116
#define RegOpenKeyEx
Definition: winreg.h:520
#define IOCTL_SCSI_GET_INQUIRY_DATA
Definition: scsi_port.h:51
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
ULONG Flags
Definition: uata_ctl.h:73
#define UNIATA_REMOVE_FLAGS_HIDE
Definition: uata_ctl.h:75
IN OUT PVCB OUT PDIRENT OUT PBCB IN BOOLEAN CreateFile
Definition: fatprocs.h:904
USHORT SectorsPerTrack
Definition: atapi.h:199
unsigned short USHORT
Definition: pedump.c:61
struct _SCSI_PASS_THROUGH SCSI_PASS_THROUGH
struct _SRB_IO_CONTROL SRB_IO_CONTROL
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
ULONG RevID
Definition: uata_ctl.h:119
#define IOCTL_SCSI_MINIPORT_UNIATA_SET_MAX_MODE
Definition: uata_ctl.h:62
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
ULONG OrigAdapterInterfaceType
Definition: uata_ctl.h:134
#define IOCTL_SCSI_MINIPORT_IDENTIFY
Definition: cdrw_hw.h:1458
USHORT ModelNumber[20]
Definition: atapi.h:206
#define ATAPI_TYPE_TAPE
Definition: atapi.h:622
ULONG MaxTransferMode
Definition: uata_ctl.h:104
ACCESS_MASK REGSAM
Definition: winreg.h:69
SRB_IO_CONTROL hdr
Definition: uata_ctl.h:295
ULONG OrigMode
Definition: uata_ctl.h:89
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
#define OPTICAL_DEVICE
Definition: cdrw_hw.h:1151
#define MEDIUM_CHANGER
Definition: cdrw_hw.h:1152
#define COMMUNICATION_DEVICE
Definition: cdrw_hw.h:1153
USHORT NumberOfCylinders
Definition: atapi.h:194
UCHAR bBuffer[1]
Definition: helper.h:27
#define ATA_UDMA2
Definition: atapi.h:329
#define READ_ONLY_DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1149
USHORT NumberOfHeads
Definition: atapi.h:196
#define IOCTL_SCSI_GET_CAPABILITIES
Definition: scsi_port.h:52
#define OUT
Definition: typedefs.h:39
#define ATA_SDMA0
Definition: atapi.h:317
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define StartStop_Power_Sleep
Definition: scsi.h:409
#define CREATE_NEW
Definition: disk.h:69
struct _SCSI_ADAPTER_BUS_INFO * PSCSI_ADAPTER_BUS_INFO
PADAPTERINFO g_AdapterInfo
Definition: atactl.cpp:43
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
void exit(int exitcode)
Definition: _exit.c:33
UCHAR bDriveNumber
Definition: helper.h:33
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
#define SCSI_IOCTL_DATA_OUT
Definition: scsi_port.h:174
#define ATA_UDMA3
Definition: atapi.h:330
#define RegOpenKey
Definition: winreg.h:519
static const WCHAR Signature[]
Definition: parser.c:141
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
#define memset(x, y, z)
Definition: compat.h:39
static const struct access_res create[16]
Definition: package.c:7720
static SERVICE_STATUS status
Definition: service.c:31
int ata_str_to_mode(char *str)
Definition: atactl.cpp:443
int k
Definition: mpi.c:3369
static unsigned char buff[32768]
Definition: fatten.c:17
#define check_atamode_str(str, mode)
Definition: atactl.cpp:436
#define RegSetValueEx
Definition: winreg.h:533
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
#define ATA_UDMA5
Definition: atapi.h:332
BOOLEAN ata_bblk(int bus_id, int dev_id, int list_bb)
Definition: atactl.cpp:1348
#define printf
Definition: config.h:203
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
void print_help()
Definition: atactl.cpp:52
#define StartStop_Power_NoChg
Definition: scsi.h:406
#define CMD_ATA_RESET
Definition: atactl.cpp:134
CHAR * _fgets(CHAR *string, int count, HANDLE stream)
Definition: atactl.cpp:1308