forked from AgileEhsan/winasm-studio
-
Notifications
You must be signed in to change notification settings - Fork 0
/
UndoRedo.asm
211 lines (209 loc) · 5.21 KB
/
UndoRedo.asm
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
UNDOTYPECREATECONTROL EQU 1
.CODE
;ResourceRedo Proc Uses EDI
;; Invoke GetWindowLong,hADialog,GWL_USERDATA
;; MOV EDI,EAX
;; .If [EDI].DIALOGDATA.lpUndoRedoMemory ;It should be checked before calling this procedure, but let's check it again
;; MOV EDX,[EDI].DIALOGDATA.lpUndoRedoMemory
;; MOV ECX,[EDX] ;ECX is nr of Undo operations
;; PrintHex ECX
;; .EndIf
; RET
;ResourceRedo EndP
;
;ResourceUndo Proc Uses EDI
;;Local Buffer[256]:BYTE ;To be erased
; Invoke GetWindowLong,hADialog,GWL_USERDATA
; MOV EDI,EAX
; .If [EDI].DIALOGDATA.lpUndoRedoMemory ;It should be checked before calling this procedure, but let's check it again
;; MOV EAX,[EDI].DIALOGDATA.lpUndoRedoMemory
;; MOV ECX,[EAX] ;ECX now holds Undo Type
;; PrintDec ECX
;;
;; ;ADD EAX,4
;; ;MOV ECX,[EAX+4] ;ECX now holds CONTROLDATA
;; MOV ECX,[EAX+4].CONTROLDATA.hWnd
;; PrintHex ECX
;
;
; MOV EAX,[EDI].DIALOGDATA.lpUndoRedoMemory
; MOV EDX,4
; @@:
; MOV ECX,[EAX] ;ECX now holds Undo Type
; .If ECX
; MOV ECX,[EAX+4].CONTROLDATA.hWnd
; PrintHex ECX
;
; ADD EDX,(SizeOf CONTROLDATA)+4
; ADD EAX,(SizeOf CONTROLDATA)+4
; JMP @B
; .EndIf
;
; .EndIf
;;
;; Invoke GetWindowLong,hADialog,GWL_USERDATA
;; MOV EDI,EAX
;; .If [EDI].DIALOGDATA.lpUndoRedoMemory ;It should be checked before calling this procedure, but let's check it again
;; MOV EDX,[EDI].DIALOGDATA.lpUndoRedoMemory
;; MOV ECX,[EDX] ;ECX is nr of UndoRedo operations
;; PrintDec ECX
;; .If ECX>0
;; PUSH EDX
;;
;; DEC ECX
;; MOV EAX,8
;; MUL ECX
;; ADD EAX,4
;;
;; POP EDX
;;
;; ADD EDX,EAX
;; MOV ECX,[EDX]
;; ;PrintDec ECX ;Type of Undo
;; ADD EDX,4
;; MOV ECX,[EDX]
;; ;PrintDec ECX ;lpControlData
;; Invoke lstrcpy,ADDR Buffer,ADDR [ECX].CONTROLDATA.Caption
;; PrintString Buffer
;; .EndIf
;; ;PrintHex ECX
;;
;; .EndIf
; RET
;ResourceUndo EndP
;
;AddUndo Proc Uses EDI dwUndoType:DWORD, lpControlData:DWORD
;
;;To Test
;;MOV EAX,lpControlData
;;MOV EAX,[EAX].CONTROLDATA.hWnd
;;PrintHex EAX
;
; Invoke GetWindowLong,hADialog,GWL_USERDATA
; MOV EDI,EAX
; .If ![EDI].DIALOGDATA.lpUndoRedoMemory
; MOV EAX, SizeOf CONTROLDATA
; PrintDec EAX
; Invoke HeapAlloc,hMainHeap,HEAP_ZERO_MEMORY,(SizeOf CONTROLDATA)+8
; ;i.e. 4 extra bytes to store dwUndoType at the begining
; ;and 4 extra bytes to let lpUndoRedoPointer rest
; MOV [EDI].DIALOGDATA.lpUndoRedoMemory,EAX
;
;
; MOV ECX,dwUndoType
; MOV [EAX],ECX
; ADD EAX,4
; PUSH EAX
; Invoke RtlMoveMemory,EAX,lpControlData,SizeOf CONTROLDATA
; POP EAX
; ADD EAX, SizeOf CONTROLDATA ;Let the lpUndoRedoPointer rest
; MOV [EDI].DIALOGDATA.lpUndoRedoPointer,EAX
;
;
; .Else
; MOV ECX,[EDI].DIALOGDATA.lpUndoRedoPointer
;
; MOV EAX,[EDI].DIALOGDATA.lpUndoRedoMemory
; SUB ECX,EAX ;ECX nr of bytes UndoRedoPointer in front of UndoRedoMemory
; ;PrintDec ECX
;
;; MOV EDX,(SizeOf CONTROLDATA)+8
;; @@:
;; MOV ECX,[EAX] ;ECX now holds Undo Type
;; .If ECX
;; ;PrintHex 1
;; ADD EDX,(SizeOf CONTROLDATA)+4
;; ADD EAX,(SizeOf CONTROLDATA)+4
;; JMP @B
;; .EndIf
;;
;; PUSH EDX ;New Size required for UndoRedoMemory
;; Invoke HeapReAlloc,hMainHeap,HEAP_ZERO_MEMORY,[EDI].DIALOGDATA.lpUndoRedoMemory,EDX
;; MOV [EDI].DIALOGDATA.lpUndoRedoMemory,EAX
;; POP EDX
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;; SUB EDX,(SizeOf CONTROLDATA)+8
;; ADD EAX,EDX
;;
;;
;; MOV ECX,dwUndoType
;; MOV [EAX],ECX
;; ADD EAX,4
;; PUSH EAX
;; Invoke RtlMoveMemory,EAX,lpControlData,SizeOf CONTROLDATA
;; POP EAX
;; ADD EAX, SizeOf CONTROLDATA ;Let the lpUndoRedoPointer rest
;; MOV [EDI].DIALOGDATA.lpUndoRedoPointer,EAX
;
;
; .EndIf
;
;
;
;; Invoke GetWindowLong,hADialog,GWL_USERDATA
;; MOV EDI,EAX
;; .If ![EDI].DIALOGDATA.lpUndoRedoMemory
;; Invoke HeapAlloc,hMainHeap,HEAP_ZERO_MEMORY,16
;; ;i.e. 4 bytes for storing nr of UndoRedo Operations
;; ;4 bytes for storing undotype
;; ;4 bytes for storing controldata
;; ;4 bytes with no data so that lpUndoRedoPointer points to it
;; MOV [EDI].DIALOGDATA.lpUndoRedoMemory,EAX
;;
;; MOV ECX,1 ;Means there is 1 UndoRedo Operation
;; MOV [EAX],ECX
;;
;; MOV ECX,dwUndoType
;; MOV [EAX+4],ECX
;;
;; MOV ECX,lpControlData
;; MOV [EAX+8],ECX
;;
;; ADD EAX,12 ;i.e lpUndoRedoPointer points to the last 4 bytes that have no data (=0)
;; MOV [EDI].DIALOGDATA.lpUndoRedoPointer,EAX
;;
;; .Else
;; MOV EDX,[EDI].DIALOGDATA.lpUndoRedoMemory
;; MOV ECX,[EDX] ;ECX is nr of Undo operations
;;
;; INC ECX
;; MOV [EDX],ECX ;Store new nr of UndoRedo operations
;;
;; MOV EAX,8
;; MUL ECX ;EAX is Size of UndoRedoMemory
;; ADD EAX,8;4 ;Add 4 more bytes to store nr of UndoRedo Operations
;; ;Add 4 more bytes so that lpUndoRedoPointer can rest there if no Redo is possible
;; ;Now EAX is total Size of UndoRedoMemory
;;
;; PUSH EAX
;; Invoke HeapReAlloc,hMainHeap,HEAP_ZERO_MEMORY,[EDI].DIALOGDATA.lpUndoRedoMemory,EAX
;;
;; MOV [EDI].DIALOGDATA.lpUndoRedoMemory,EAX
;;
;; POP ECX
;; SUB ECX,12;8
;; ADD EAX,ECX
;;
;;
;; MOV ECX,dwUndoType
;; MOV [EAX],ECX
;;
;; MOV ECX,lpControlData
;; MOV [EAX+4],ECX
;;
;; .EndIf
; RET
;AddUndo EndP