; ?????????????????????????????????????
include masm32rt.inc
; ?????????????????????????????????????
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
GetPhysicalDriveHandles PROTO
ClosePhysicalDriveHandles PROTO
GetReadWriteActivity PROTO
; ?????????????????????????????????????
IOCTL_DISK_GET_DRIVE_GEOMETRY EQU 70000H
IOCTL_DISK_PERFORMANCE EQU 70020H
ERROR_INSUFFICIENT_BUFFER EQU 122
MAX_IDE_DRIVES EQU 16 ; Max number of drives assuming primary/secondary, master/slave topology
IDI_TASKBARICON equ 0
WM_CALLBACK equ WM_USER + 100
IDM_EXIT equ 1000
ID_TIMER equ 1
; ?????????????????????????????????????
DISK_PERFORMANCE STRUCT
BytesRead LARGE_INTEGER <> ; Cumulative count of bytes read from the disk since the performance counters were enabled.
BytesWritten LARGE_INTEGER <> ; Cumulative count of bytes written to the disk since the performance counters were enabled.
ReadTime LARGE_INTEGER <> ; Cumulative time, expressed in increments of 100 nanoseconds, spent on disk reads since the performance counters were enabled.
WriteTime LARGE_INTEGER <> ; Cumulative time, expressed in increments of 100 nanoseconds, spent on disk writes since the performance counters were enabled.
IdleTime LARGE_INTEGER <> ; Cumulative time, expressed in increments of 100 nanoseconds, since the performance counters were enabled in which there was no disk activity
ReadCount DWORD ? ; Number of disk accesses for reads since the performance counters were enabled.
WriteCnt DWORD ? ; Number of disk accesses for writes since the performance counters were enabled.
QueueDepth DWORD ? ; Snapshot of the number of queued disk I/O requests at the time that the query for performance statistics was performed.
SplitCount DWORD ? ; number of disk accesses by means of an associated IRP since the performance counters were enabled.
QueryTime LARGE_INTEGER <> ; Timestamp indicating the system time at the moment that the query took place.
StorageDevNumber DWORD ? ; Unique number assigned to every disk or volume across a particular storage type. The storage types are disk.sys, ftdisk.sys, and dmio.sys.
StorageMngrName WCHAR 8 DUP (?) ; 8-character string that indicates which device driver provided the performance statistics.
Reserved DWORD ? ; 4 Fillbytes, without them DeviceIoControl function returns ERROR_INSUFFICIENT_BUFFER
DISK_PERFORMANCE ENDS
DISK_DATA STRUCT
hDevice DWORD ?
ReadCnt DWORD ?
WriteCnt DWORD ?
DISK_DATA EndS
; ?????????????????????????????????????
.data?
commandLine DWORD ?
hInstance DWORD ?
hWnd DWORD ?
hPopupMenu DWORD ?
hIconNA DWORD ?
hIconRead DWORD ?
hIconWrite DWORD ?
hIconRW DWORD ?
hActIcon DWORD ?
nid NOTIFYICONDATA <>
; ?????????????????????????????????????
.data
dwReads DWORD 0
dwWrites DWORD 0
dskdata DISK_DATA MAX_IDE_DRIVES DUP (<0,0,0>)
szDevName DB "
className DB "HddActivityClass",0
windowName DB " HDD Activity ",0
winName DB 128 dup (0)
; ?????????????????????????????????????
.code
start:
mov hInstance, rv(GetModuleHandle, NULL)
mov commandLine, rv(GetCommandLine)
Invoke WinMain, hInstance, NULL, commandLine, SW_SHOWDEFAULT
Invoke ExitProcess, eax
; ?????????????????????????????????????
WinMain proc hInst:DWORD,hPrevInst:DWORD,cmdLine:DWORD,cmdShow:DWORD
LOCAL wc :WNDCLASSEX
LOCAL msg :MSG
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW \
or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
m2m wc.hInstance, hInst
mov wc.hbrBackground, COLOR_WINDOW+1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, OFFSET className
mov wc.hIcon, NULL
mov wc.hCursor, NULL
mov wc.hIconSm, 0
Invoke RegisterClassEx, ADDR wc
Invoke CreateWindowEx, WS_EX_OVERLAPPEDWINDOW,
ADDR className,
ADDR winName,
WS_OVERLAPPEDWINDOW,
0,0,240,160,
NULL, NULL,
hInst, NULL
mov hWnd, eax
Invoke SetTimer, hWnd, ID_TIMER, 100, NULL
msgLoop:
Invoke GetMessage, ADDR msg, NULL, 0, 0
.IF eax != 0
Invoke TranslateMessage, ADDR msg
Invoke DispatchMessage, ADDR msg
jmp msgLoop
.ENDIF
Invoke KillTimer, hWnd, ID_TIMER
return msg.wParam
fail:
return 0
WinMain endp
; ?????????????????????????????????????
WndProc proc hWin:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
LOCAL pt:POINT
.IF uMsg == WM_CREATE
mov hIconRW, rv(LoadImage,hInstance,1000,IMAGE_ICON,0,0,NULL)
mov hIconRead, rv(LoadImage,hInstance,2000,IMAGE_ICON,0,0,NULL)
mov hIconWrite, rv(LoadImage,hInstance,3000,IMAGE_ICON,0,0,NULL)
mov hIconNA, rv(LoadImage,hInstance,4000,IMAGE_ICON,0,0,NULL)
mov hPopupMenu, rv(CreatePopupMenu)
Invoke AppendMenu, hPopupMenu, MF_STRING, IDM_EXIT, chr$("Exit")
mov nid.cbSize, SIZEOF NOTIFYICONDATA
m2m nid.hwnd, hWin
mov nid.uID, IDI_TASKBARICON
mov nid.uFlags, NIF_ICON+NIF_MESSAGE+NIF_TIP
mov nid.uCallbackMessage, WM_CALLBACK
m2m nid.hIcon, hIconNA
Invoke lstrcpy, ADDR nid.szTip, ADDR winName
Invoke Shell_NotifyIcon, NIM_ADD, ADDR nid
.ELSEIF uMsg == WM_DESTROY
Invoke PostQuitMessage, NULL
return 0
.ELSEIF uMsg == WM_TIMER
call TimerProc
.ELSEIF uMsg == WM_COMMAND
.IF lParam == 0
Invoke Shell_NotifyIcon, NIM_DELETE, ADDR nid
mov eax, wParam
.IF ax == IDM_EXIT
Invoke DestroyWindow, hWin
.ENDIF
.ENDIF
.ELSEIF uMsg == WM_CALLBACK
.IF wParam == IDI_TASKBARICON
.IF lParam == WM_RBUTTONDOWN
; -------------------------------------------------------
; This code temporarily sets the foreground window to
; the current window to correct a problem with the menu
; not disappearing when the user clicks outside the menu.
; Tested under Windows 2000 only. See the PSDK or MSDN
; documentation for TrackPopupMenu.
; -------------------------------------------------------
Invoke GetForegroundWindow
push eax
Invoke SetForegroundWindow, hWin
Invoke GetCursorPos,addr pt
Invoke TrackPopupMenu, hPopupMenu, TPM_RIGHTALIGN,
pt.x, pt.y, NULL, hWin, NULL
pop eax
Invoke SetForegroundWindow, eax
.ENDIF
.ENDIF
.ENDIF
Invoke DefWindowProc, hWin, uMsg, wParam, lParam
ret
WndProc endp
; ?????????????????????????????????????
TimerProc proc
Invoke GetPhysicalDriveHandles
.IF eax == 1
Invoke wsprintf,ADDR winName,SADD(" HDD Activity ",13,10," %u drive detected "),eax
.ELSEIF
Invoke wsprintf,ADDR winName,SADD(" HDD Activity ",13,10," %u drives detected "),eax
.ENDIF
Invoke GetReadWriteActivity
.IF eax == 0
m2m nid.hIcon,hIconNA
.ELSEIF eax == 1
m2m nid.hIcon,hIconRead
.ELSEIF eax == 2
m2m nid.hIcon,hIconWrite
.ELSEIF eax == 3
m2m nid.hIcon,hIconRW
.ENDIF
mov eax,nid.hIcon
.IF eax != hActIcon
Invoke lstrcpy,ADDR nid.szTip,ADDR winName
Invoke Shell_NotifyIcon,NIM_MODIFY,ADDR nid
m2m hActIcon,nid.hIcon
.ENDIF
invoke ClosePhysicalDriveHandles
ret
TimerProc endp
; ?????????????????????????????????????
GetPhysicalDriveHandles PROC USES ebx
Local dwNumDrives:DWORD
Local szBuf[128]:BYTE
mov ecx,MAX_IDE_DRIVES-1
mov dwNumDrives,0
lea ebx,dskdata+SIZEOF dskdata
ASSUME EBX:PTR DISK_DATA
@@:
push ecx
sub ebx,SIZEOF DISK_DATA
Invoke wsprintf,ADDR szBuf,ADDR szDevName,ecx
Invoke CreateFile,ADDR szBuf,0,FILE_SHARE_READ or FILE_SHARE_WRITE,NULL,OPEN_EXISTING,NULL,0
mov [ebx].hDevice,eax
sub eax,INVALID_HANDLE_VALUE
jz _next
add dwNumDrives,1
_next:
pop ecx
sub ecx,1
jns @B
ASSUME EBX:NOTHING
mov eax,dwNumDrives
Ret
GetPhysicalDriveHandles EndP
; ?????????????????????????????????????
ClosePhysicalDriveHandles Proc USES ebx
mov ecx,MAX_IDE_DRIVES-1
lea ebx,dskdata+SIZEOF dskdata
ASSUME EBX:PTR DISK_DATA
@@:
push ecx
sub ebx,SIZEOF DISK_DATA
.if [ebx].hDevice != INVALID_HANDLE_VALUE
Invoke CloseHandle, [ebx].hDevice
.endif
pop ecx
sub ecx,1
jns @B
ASSUME EBX:NOTHING
Ret
ClosePhysicalDriveHandles EndP
; ?????????????????????????????????????
GetReadWriteActivity Proc USES ebx
Local pdf:DISK_PERFORMANCE
Local dwCnt:DWORD
Local dwCurReads:DWORD
Local dwCurWrites:DWORD
Local szBuf[128]:BYTE
xor eax,eax
ASSUME EBX:PTR DISK_DATA
mov ecx,MAX_IDE_DRIVES-1
lea ebx,dskdata+SIZEOF dskdata
mov dwCurReads,eax
mov dwCurWrites,eax
@@:
push ecx
sub ebx,SIZEOF DISK_DATA
.if [ebx].hDevice != INVALID_HANDLE_VALUE
Invoke DeviceIoControl,[ebx].hDevice,IOCTL_DISK_PERFORMANCE,NULL,0,ADDR pdf,SizeOf pdf,ADDR dwCnt,NULL
add eax,eax
jz err
mov eax,pdf.ReadCount
mov edx,pdf.WriteCnt
add dwCurReads,eax
add dwCurWrites,edx
.endif
err:
pop ecx
sub ecx,1
jns @B
xor eax,eax
; Check for READ activity
mov edx,dwReads
mov ecx,dwCurReads
sub edx,ecx
jz @F
or eax,1
mov dwReads,ecx
@@:
; Check for WRITE activity
mov edx,dwWrites
mov ecx,dwCurWrites
sub edx,ecx
jz @F
or eax,2
mov dwWrites,ecx
@@:
ASSUME EBX:NOTHING
Ret
GetReadWriteActivity EndP
end start