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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
| .386
.MODEL FLAT
L EQU <LARGE>
; Значення параметра функції GetStdHandle
STD_INPUT_HANDLE EQU -10 ; дескриптор стандартного вхідного потоку
STD_OUTPUT_HANDLE EQU -11 ; дескриптор стандартного вихідного потоку
STD_ERROR_HANDLE EQU -12 ; дескриптор стандартного потоку помилок
;*******************************************************************
;Параметри пристрою IDE/ATAPI
;********************************************************************
SCANDEVENTRY STRUC
sde_wBasePort DW ?
sde_bDevNum DB ?
sde_lpszPort DD ?
SCANDEVENTRY ENDS
EXTRN hStdOut:DWORD
EXTRN ExitProcess:PROC
EXTRN GetStdHandle:PROC
EXTRN WaitForSingleObject:PROC
EXTRN _wsprintfA:PROC
EXTRN lstrcpynA:PROC
EXTRN GetVersionExA:PROC
.DATA
szPriMaster DB "=========Primary Master===========", 0Dh, 0Ah, 0
szPriSlave DB "============Primary Slave==========", 0Dh, 0Ah, 0
szSecMaster DB "==============Secondary Master=====", 0Dh, 0Ah, 0
szSecSlave DB "===========Secondary Slave=========", 0Dh, 0Ah, 0
szTerMaster DB "===========Tertiary Master=========", 0Dh, 0Ah, 0
szTerSlave DB "==========Tertiary Slave===========", 0Dh, 0Ah, 0
szQuaMaster DB "==========Quaternary Master========", 0Dh, 0Ah, 0
szQuaSlave DB "==========Quaternary Slave=========", 0Dh, 0Ah, 0
szDevice DB " Device: %s", 0Dh, 0Ah, 0
szModel DB " Model: %s", 0Dh, 0Ah, 0
szFirmwareRev DB "Firmware Revision: %s", 0Dh, 0Ah, 0
szSerNum DB " Serial Number: %s", 0Dh, 0Ah, 0
szHDD DB "HDD %uM", 0
szUnknown DB "Unknown", 0
szPressAnyKey DB 0Dh, 0Ah, "Press any key...", 0
ScanDevices SCANDEVENTRY <1F0h,0,OFFSET szPriMaster>
SCANDEVENTRY <1F0h,1,OFFSET szPriSlave>
SCANDEVENTRY <170h,2,OFFSET szSecMaster>
SCANDEVENTRY <170h,3,OFFSET szSecSlave>
SCANDEVENTRY <1E8h,4,OFFSET szTerMaster>
SCANDEVENTRY <1E8h,5,OFFSET szTerSlave>
SCANDEVENTRY <168h,6,OFFSET szQuaMaster>
SCANDEVENTRY <168h,7,OFFSET szQuaSlave>
SCANDEVICESCOUNT = ($-ScanDevices)/SIZE SCANDEVENTRY
.DATA
DevInfo DW 256h
.CODE
EXTRN puts:PROC
EXTRN fputs:PROC
EXTRN printf:PROC
EXTRN Ring0Call:PROC
EXTRN GetATAPIDevInfo:PROC ; отримання інформації про пристрій ATAPI
EXTRN GetIDEDevInfo:PROC ; отримання інформації про пристрій IDE
EXTRN DetectATAPIDev:PROC ; перевірка чи пристрій ATAPI
EXTRN NT_GetDevInfo:PROC
Start:
push L STD_OUTPUT_HANDLE
call GetStdHandle
inc eax
jz Exit ; якщо еах = 0 - перехід на Exit, інакше - якщо еах = 1
dec eax
mov [hStdOut],eax
mov ebp,OFFSET W9x_GetDevInfo ; ebp = інформація про IDE/ATAPI(Win9x)
jnz @@ScanDevices ; якщо недорівнює 0 - перехід
mov ebp,OFFSET NT_GetDevInfo
@@ScanDevices:
;Сканування пристрою IDE/ATAPI
mov esi,OFFSET ScanDevices ;ESI -> ScanDevices
mov edi,OFFSET DevInfo ;EDI -> DevInfo
mov ecx,SCANDEVICESCOUNT
@@DevLoop: push ecx
;Отримання інформації про пристрій IDE/ATAPI
mov dx,[(SCANDEVENTRY PTR esi).sde_wBasePort]
mov al,[(SCANDEVENTRY PTR esi).sde_bDevNum]
call ebp
or eax,eax ;інформація отримана?
jz @@NextDev ; перехід, якщо =0, інакше - якщо =1
;Вивід інформації про пристрій IDE/ATAPI
push [(SCANDEVENTRY PTR esi).sde_lpszPort]
call puts
call PrintDevInfo ; вивід інформації про пристрій IDE/ATAPI
@@NextDev: pop ecx
add esi,SIZE SCANDEVENTRY
loop @@DevLoop
;Очікування натискання клавіші
push L STD_ERROR_HANDLE
call GetStdHandle ; виведення повідомлення "Press any key"
push L OFFSET szPressAnyKey
push eax
call fputs
push L STD_INPUT_HANDLE
call GetStdHandle
inc eax
jz Exit
dec eax
push L 0FFFFFFFFh
push eax
call WaitForSingleObject
Exit:
push L 0
call ExitProcess
;********************************************************************
;PrintDevInfo вивід інформації про пристрій IDE/ATAPI
;********************************************************************
;Використовує: lstrcpynA, printf
;
;Виклик: EDI -> буфер з інформацією про пристрій
;
;Виклик: ні
;
;Змінювані регістри: EAX,ECX,EDX,Flags
;********************************************************************
PrintDevInfo PROC
LOCAL @@szTemp:BYTE:64 = LOCAL_SIZE
enter LOCAL_SIZE,0
push esi
lea esi,[@@szTemp] ;ESI -> @@szTemp
;Тип пристрою
mov al,[edi+1]
test al,80h ;пристрій ATAPI?
jz @@IDE
and al,1Fh ;AL = тип пристрою ATAPI
cmp al,5
mov eax,OFFSET szUnknown
je @@PrintDeviceType
mov eax,OFFSET szUnknown
jmp @@PrintDeviceType
@@IDE:
; Жорсткий диск IDE
mov eax,DWORD PTR [edi+120] ;EAX = загальна кількість секторів
;в режимі LBA
cmp eax,16515072
jae @@GetSizeInMB ; перехід, якщо більше рівне для цілого без знаку
movzx eax,WORD PTR [edi+2]
movzx ecx,WORD PTR [edi+6]
mul ecx
movzx ecx,WORD PTR [edi+12]
mul ecx
;визначити розмір в Мб
@@GetSizeInMB: mov ecx,512
mul ecx ; есх = есх * 512
mov ecx,500000
div ecx ; есх\500000
shr eax,1 ; зсув есх на 1 розряд
adc eax,0 ; еах = еах + 0
push eax
push L OFFSET szHDD
push esi
call _wsprintfA
add esp,12
mov eax,esi
; вивести тип пристрою
@@PrintDeviceType:
push eax
push L OFFSET szDevice
call printf
add esp,8
;Модель
cmp WORD PTR [edi+54],0
je @@Model_Done
push L 41
lea eax,[edi+54]
push eax
push esi
call lstrcpynA
push esi
push L OFFSET szModel
call printf
add esp,8
@@Model_Done:
;Firmware Revision
cmp WORD PTR [edi+46],0
je @@FirmwareRev_Done
push L 9
lea eax,[edi+46]
push eax
push esi
call lstrcpynA
push esi
push L OFFSET szFirmwareRev
call printf
add esp,8
@@FirmwareRev_Done:
;Серійний номер
cmp WORD PTR [edi+20],0
je @@SerNum_Done
push L 21
lea eax,[edi+20]
push eax
push esi
call lstrcpynA
push esi
push L OFFSET szSerNum
call printf
add esp,8
@@SerNum_Done:
pop esi
leave
ret
PrintDevInfo ENDP
;********************************************************************
;Параметри, що передаються в процедуру Ring0_GetDevInfo
;********************************************************************
GETDEVINFOPARAMS STRUC
gdip_wBasePort DW ?
gdip_bDevNum DB ?
gdip_lpBuffer DD ?
GETDEVINFOPARAMS ENDS
;********************************************************************
;W9x_GetDevInfo отримуємо інформацію про пристрій IDE/ATAPI (Win9x)
;********************************************************************
; Використовує: Ring0Call, Ring0_GetDevInfo
;
; Виклик: DX = базовий порт
; AL = номер пристрою
; EDI -> буфер для інформації про пристрій
;
;Повернення: EAX = флаг успешного/неудачного завершення
;
;Змінні регістри: EAX,ECX,DX,Flags
;********************************************************************
W9x_GetDevInfo PROC
LOCAL @@gdip:GETDEVINFOPARAMS, @@fSuccess:DWORD = LOCAL_SIZE
enter LOCAL_SIZE,0
mov [@@gdip.gdip_wBasePort],dx
mov [@@gdip.gdip_bDevNum],al
mov [@@gdip.gdip_lpBuffer],edi
lea eax,[@@fSuccess]
push eax
lea eax,[@@gdip]
push eax
push L OFFSET Ring0_GetDevInfo
call Ring0Call
or eax,eax ;процедура виконана ?
jz @@Exit
mov eax,[@@fSuccess]
@@Exit: leave
ret
W9x_GetDevInfo ENDP
;********************************************************************
;Ring0_GetDevInfo отримуємо інформацію про пристрій IDE/ATAPI
;викликається з Ring 0
;********************************************************************
;використовує: DetectATAPIDev, GetATAPIDevInfo, GetIDEDevInfo
;
;виклик: ECX -> параметри для отримання інформації(GETDEVINFOPARAMS)
;
;повернення: EAX = флаг успешного/неудачного завершення
;
;Змінні регістри: EAX,ECX,DX,Flags
;********************************************************************
Ring0_GetDevInfo PROC FAR
push edi
mov dx,[(GETDEVINFOPARAMS PTR ecx).gdip_wBasePort]
mov al,[(GETDEVINFOPARAMS PTR ecx).gdip_bDevNum]
mov edi,[(GETDEVINFOPARAMS PTR ecx).gdip_lpBuffer]
push eax
push edx
call DetectATAPIDev ;пристрій ATAPI?
pop edx
pop eax
jc @@TryIDE
call GetATAPIDevInfo ;отримує інформацію
;про пристрій ATAPI
jmp @@Exit
@@TryIDE: call GetIDEDevInfo ;отримати інформацію
;про пристрій IDE
setnc al
movzx eax,al
pop edi
ret
Ring0_GetDevInfo ENDP
ENDP
END Start |