In this tutorial, we will address that issue by handling the WM_PASTE message. This will intercept the WM_PASTE message, trim any leading and trailing spaces/tabs, check the length of the text to be pasted, and check for a valid IP address, then if all is good, write the modified text back to the clipboard and allow pasting.
This subclass will be a bit different as I chose to use a lookup table to check for valid characters typed.
the modified subclass proc:
SubClassNumbers proc uses esi edi ebx hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
mov eax, uMsg
cmp eax, WM_CHAR
je _CHAR
cmp eax, WM_PASTE
je _PASTE
PassThrough:
invoke CallWindowProc, lpNumberProc, hWin, uMsg, wParam, lParam
ret
_CHAR:
mov eax, wParam
mov ecx, offset TableNums
movzx edx, byte ptr [ecx + eax]
test edx, edx
jz NotWanted
jmp PassThrough
_PASTE:
invoke OpenClipboard, NULL
test eax, eax
jz PassThrough
invoke GetClipboardData, CF_TEXT
test eax, eax
jz PasteDone
mov esi, eax
invoke szTrim, esi
invoke szLen, esi
test eax, eax
jnz CheckIPLen
invoke CloseClipboard
jmp NotWanted
CheckIPLen:
cmp eax, 15
jg BadIP
CheckDots:
invoke szWcnt, esi, offset szDot
cmp eax, 3
jne BadIP
CheckMask0:
invoke Cmpi, esi, offset szIP0
test eax, eax
jz BadIP
CheckMask255:
invoke Cmpi, esi, offset szIP255
jz BadIP
IsValidIP:
invoke inet_addr, esi
cmp eax, INADDR_NONE
je BadIP
CopyModified:
invoke szLen, esi
inc eax
invoke GlobalAlloc, GHND, eax
mov edi, eax
invoke GlobalLock, eax
mov ebx, eax
invoke szCopy, esi, ebx
invoke EmptyClipboard
invoke GlobalUnlock, ebx
invoke SetClipboardData, CF_TEXT, edi
MemDone:
invoke GlobalFree, edi
PasteDone:
invoke CloseClipboard
jmp PassThrough
BadIP:
invoke GlobalUnlock, esi
invoke CloseClipboard
invoke MessageBox, hWin, offset szErrBadIPPasteText, offset szErrBadIPTitle, MB_IConerror
NotWanted:
xor eax, eax
ret
SubClassNumbers endp
This subclass we will only allow numbers and a period to be entered or pasted. A simple IPv4 edit control.
_CHAR:
mov eax, wParam
mov ecx, offset TableNums
movzx edx, byte ptr [ecx + eax]
test edx, edx
jz NotWanted
jmp PassThrough
wParam will contain the character code of the key pressed, this is the same as the ASCII code for the character, so we will use this as our index into our lookup table.
This is a bit overkill for this, but it is to show a different way to do it. The lookup table is a 256 byte table covering the ASCII and Extended ASCII characters. It contains ones and zeros. Any character that you want to allow, it will be a 1 in the table, and any character you do not want, will be a 0. Here is our lookup table allowing 0 - 9 (ASCII code 48 - 57) and a period (ASCII code 46).
TableNums BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 BYTE 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Let's say the letter "a" was pressed, the ASCII code is 97. We then tell the CPU to take the address of our lookup table (in ecx) and add 97 to that address, and move that value into edx while zeroing out unused bits - movzx edx, byte ptr [ecx + eax], next we check to see if the value is 0 or 1 with test edx, edx, this is the same as and except it does not modify any flags. If the value is 0, we return 0 from the callback to prevent the character from being displayed, if it is 1, the key is wanted, so we pass the keypress on to windows to do it's thing with CallWindowProc
Now to handle WM_PASTE. We need to get the contents of the clipboard, trim any leading and trailing spaces and tabs, do some checks and write back to clipboard then allow paste. An IPv4 address can be 15 characters long, so we need to check the length, check to see if it is 0.0.0.0 or 255.255.255.255, then check to see if values are in range. (this is from a program, and the 2 IP masks are not valid for the program.)
invoke OpenClipboard, NULL
test eax, eax
jz PassThrough
invoke GetClipboardData, CF_TEXT
test eax, eax
jz PasteDone
mov esi, eax
We first open the clipboard and if that failed, we pass the message on silently, you could notify user if wanted. OpenClipboard returns 0 on failure.
Next we attempt to get the text from the clipboard, GetClipboardData returns 0 on failure or a handle to the clipboard object we requested which you seem to be able to treat this as a pointer. We will save this pointer to esi.
invoke szTrim, esi
invoke szLen, esi
test eax, eax
jnz CheckIPLen
invoke CloseClipboard
jmp NotWanted
Now we trim any leading and trailing spaces and tabs, then check the length, if only spaces or tabs were on the clipboard, the len will be zero and we don't want that, so we CloseClipboard and return 0. For every successful call to OpenClipboard, you must call CloseClipboard
CheckIPLen:
cmp eax, 15
jg BadIP
CheckDots:
invoke szWcnt, esi, offset szDot
cmp eax, 3
jne BadIP
CheckMask0:
invoke Cmpi, esi, offset szIP0
test eax, eax
jz BadIP
CheckMask255:
invoke Cmpi, esi, offset szIP255
jz BadIP
IsValidIP:
invoke inet_addr, esi
cmp eax, INADDR_NONE
je BadIP
CheckIPLen checks to see if the text is more that 15 characters, and if it is; notify and return 0
CheckDots checks to see if we have 3 periods, if less or more; notify and return 0
CheckMask0 compares the text to 0.0.0.0 and if equal, it is not wanted; notify and return 0
CheckMask255 compares the text to 255.255.255.255 and if equal, it is not wanted; notify and return 0
IsValidIP passes the text to inet_addr and lets it check for validity, if bad notify and return 0.
Now that we have passed all checks, if we modified the text in any way, we need to copy it back to the clipboard and allow the paste to take place.
CopyModified:
invoke szLen, esi
inc eax
invoke GlobalAlloc, GHND, eax
mov edi, eax
invoke GlobalLock, eax
mov ebx, eax
invoke szCopy, esi, ebx
invoke EmptyClipboard
invoke GlobalUnlock, ebx
invoke SetClipboardData, CF_TEXT, edi
MemDone:
invoke GlobalFree, edi
PasteDone:
invoke CloseClipboard
jmp PassThrough
This is straight forward - Get the length of the modified text, add 1 to the length for the NULL. Allocate memory with GlobalAlloc, lock the memory, copy modified text to the alloc'd memory, empty the clipboard, and put our modified text onto the clipboard. We don't return 0 but, pass WM_PASTE on to windows to allow it to do its thing.
Attached File(s)
-
EditPaste.zip (3.99K)
Number of downloads: 86







MultiQuote


|