-
Notifications
You must be signed in to change notification settings - Fork 3
/
windows.c
124 lines (103 loc) · 3.59 KB
/
windows.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2017 Jannik Vogel
// Licensed under GPLv3 or any later version.
// Refer to the LICENSE.txt file included.
#include <stddef.h>
#include <stdio.h>
#include <tchar.h>
#include <time.h>
#include <windows.h>
#include "platform.h"
#define SCSI_IOCTL_DATA_OUT 0
#define SCSI_IOCTL_DATA_IN 1
#define IOCTL_SCSI_PASS_THROUGH_DIRECT 0x0004D014
#define SENSE_BUFFER_LENGTH 32
typedef struct _SCSI_PASS_THROUGH_DIRECT {
unsigned short Length;
unsigned char ScsiStatus;
unsigned char PathId;
unsigned char TargetId;
unsigned char Lun;
unsigned char CdbLength;
unsigned char SenseInfoLength;
unsigned char DataIn;
unsigned long DataTransferLength;
unsigned long TimeOutValue;
void *DataBuffer;
unsigned long SenseInfoOffset;
unsigned char Cdb[16];
} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
typedef struct _SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER {
SCSI_PASS_THROUGH_DIRECT sptd;
unsigned long Filler;
unsigned char ucSenseBuf[SENSE_BUFFER_LENGTH];
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
char drive;
HANDLE drivehandle;
int getdrive(char *arg) {
if (strlen(arg) > 2) return 1;
if (strlen(arg) == 2 && arg[1] != ':') return 1;
if (arg[0] < 'A' || arg[0] > 'z') return 1;
if (arg[0] > 'Z' && arg[0] < 'a') return 1;
drive = arg[0];
if (drive > 'Z') drive -= ('a' - 'A');
return 0;
}
int opendrive() {
LPTSTR drivepath;
if((drivepath = (LPTSTR)calloc(sizeof("\\\\.\\.:"), sizeof(TCHAR))) == NULL) {
fprintf(stderr, "Drivepath calloc failed. Out of memory?\n");
return 1;
}
_stprintf(drivepath, _T("\\\\.\\%c:"), drive);
drivehandle = CreateFile(drivepath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (drivehandle == INVALID_HANDLE_VALUE) {
fprintf(stderr, "%s: Could not open drive %c:.\n", executable, drive);
return 1;
}
return 0;
}
void closedrive() {
CloseHandle(drivehandle);
}
unsigned long long millisecondstime() {
SYSTEMTIME currenttime;
time_t unixtime = time(NULL);
GetSystemTime(¤ttime);
return ((unixtime * 1000) + currenttime.wMilliseconds);
}
int sendcdb(const unsigned char *cdb, unsigned char cdblength, unsigned char *buffer, size_t size, int in, unsigned int *sense) {
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb;
long unsigned int returned;
memset(&sptdwb, 0, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));
memset(buffer, 0, size);
sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
sptdwb.sptd.CdbLength = cdblength;
sptdwb.sptd.SenseInfoLength = sizeof(sptdwb.ucSenseBuf);
sptdwb.sptd.DataIn = (in ? SCSI_IOCTL_DATA_IN : SCSI_IOCTL_DATA_OUT);
sptdwb.sptd.DataTransferLength = size;
sptdwb.sptd.TimeOutValue = 20;
sptdwb.sptd.DataBuffer = buffer;
sptdwb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
memcpy(sptdwb.sptd.Cdb, cdb, cdblength);
if (!DeviceIoControl(drivehandle,
IOCTL_SCSI_PASS_THROUGH_DIRECT,
&sptdwb,
sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
&sptdwb,
sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
&returned,
NULL
)) {
*sense = 1;
return 1;
}
*sense = ((sptdwb.ucSenseBuf[2] & 0x0f) << 16) + (sptdwb.ucSenseBuf[12] << 8) + sptdwb.ucSenseBuf[13];
return 0;
}