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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
/*++
Copyright (C) Microsoft Corporation, 1991 - 1999
Module Name:
history.c
Abstract:
Packet history routines for CLASSPNP
Environment:
kernel mode only
Notes:
Revision History:
--*/
#include "classp.h"
#include "debug.h"
#ifdef DEBUG_USE_WPP
#include "history.tmh"
#endif
//#ifdef ALLOC_PRAGMA
// #pragma alloc_text(PAGE, InitializeTransferPackets)
//#endif
VOID HistoryInitializeRetryLogs(_Out_ PSRB_HISTORY History, ULONG HistoryCount) {
ULONG tmpSize = HistoryCount * sizeof(SRB_HISTORY_ITEM);
tmpSize += sizeof(SRB_HISTORY) - sizeof(SRB_HISTORY_ITEM);
RtlZeroMemory(History, tmpSize);
History->TotalHistoryCount = HistoryCount;
return;
}
VOID HistoryLogSendPacket(TRANSFER_PACKET * Pkt) {
PSRB_HISTORY history;
PSRB_HISTORY_ITEM item;
NT_ASSERT( Pkt->RetryHistory != NULL );
history = Pkt->RetryHistory;
// sending a packet implies a new history unit is to be used.
NT_ASSERT( history->UsedHistoryCount <= history->TotalHistoryCount );
// if already all used up, request class driver to remove at least one history unit
if (history->UsedHistoryCount == history->TotalHistoryCount )
{
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Pkt->Fdo->DeviceExtension;
PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
NT_ASSERT( fdoData->InterpretSenseInfo != NULL );
NT_ASSERT( fdoData->InterpretSenseInfo->Compress != NULL );
fdoData->InterpretSenseInfo->Compress( fdoExtension->DeviceObject, history );
NT_ASSERT( history->UsedHistoryCount < history->TotalHistoryCount );
}
// thus, since we are about to increment the count, it must now be less...
NT_ASSERT( history->UsedHistoryCount < history->TotalHistoryCount );
// increment the number of history units in use
history->UsedHistoryCount++;
// determine index to use
item = &( history->History[ history->UsedHistoryCount-1 ] );
// zero out the history item
RtlZeroMemory(item, sizeof(SRB_HISTORY_ITEM));
// Query the tick count and store in the history
KeQueryTickCount(&item->TickCountSent);
return;
}
VOID HistoryLogReturnedPacket(TRANSFER_PACKET *Pkt) {
PSRB_HISTORY history;
PSRB_HISTORY_ITEM item;
UCHAR senseSize;
PVOID senseInfoBuffer;
UCHAR senseInfoBufferLength;
SENSE_DATA convertedSenseBuffer = {0};
BOOLEAN validSense = TRUE;
NT_ASSERT( Pkt->RetryHistory != NULL );
history = Pkt->RetryHistory;
NT_ASSERT( history->UsedHistoryCount <= history->TotalHistoryCount );
item = &( history->History[ history->UsedHistoryCount-1 ] );
// Query the tick count and store in the history
KeQueryTickCount(&item->TickCountCompleted);
// Copy the SRB Status...
item->SrbStatus = Pkt->Srb->SrbStatus;
//
// Process sense data
//
senseInfoBuffer = ClasspTransferPacketGetSenseInfoBuffer(Pkt);
senseInfoBufferLength = ClasspTransferPacketGetSenseInfoBufferLength(Pkt);
if (IsDescriptorSenseDataFormat(senseInfoBuffer)) {
validSense = ScsiConvertToFixedSenseFormat(senseInfoBuffer,
senseInfoBufferLength,
(PVOID)&convertedSenseBuffer,
sizeof(convertedSenseBuffer));
if (validSense) {
senseInfoBuffer = (PVOID)&convertedSenseBuffer;
senseInfoBufferLength = sizeof(convertedSenseBuffer);
}
}
RtlZeroMemory(&(item->NormalizedSenseData), sizeof(item->NormalizedSenseData));
if (validSense) {
// Determine the amount of valid sense data
if (!ScsiGetTotalSenseByteCountIndicated(senseInfoBuffer,
senseInfoBufferLength,
&senseSize)) {
senseSize = senseInfoBufferLength;
}
// Normalize the sense data copy in the history
senseSize = min(senseSize, sizeof(item->NormalizedSenseData));
RtlCopyMemory(&(item->NormalizedSenseData),
senseInfoBuffer,
senseSize
);
}
return;
}
|