-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
CFile.asm
351 lines (290 loc) · 9.16 KB
/
CFile.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
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
349
350
351
ifndef __UNICODE__
__UNICODE__ equ 1
endif
ifndef _CFile_
_CFile_ equ 1
include C:\masm32\include\windows.inc
include C:\masm32\include\user32.inc
include C:\masm32\include\kernel32.inc
include C:\masm32\include\comdlg32.inc
include C:\masm32\include\masm32.inc
include C:\masm32\include\msvcrt.inc
include C:\masm32\macros\macros.asm
;includelib C:\masm32\lib\masm32.lib
;includelib C:\masm32\lib\user32.lib
;includelib C:\masm32\lib\kernel32.lib
;includelib C:\masm32\lib\comdlg32.lib
;includelib C:\masm32\lib\msvcrt.lib
; NEWOBJECT ClassName, Param1
; mov hNewObject, eax
; invoke GetProcessHeap
; invoke HeapAlloc, eax, NULL, SIZEOF CFile
; push eax
; invoke CFile_Init, eax
; pop eax
;
;
; --=====================================================================================--
; CLASS METHOD PROTOS
; --=====================================================================================--
CFile_Init PROTO :DWORD
CFile_OpenFile PROTO :DWORD, :DWORD
CFile_CloseFile PROTO :DWORD
CFile_Dispose PROTO :DWORD
; --=====================================================================================--
; FUNCTION POINTER PROTOS
; --=====================================================================================--
CFile_destructorPto TYPEDEF PROTO :DWORD
.data?
; --=====================================================================================--
; CLASS STRUCTURE
; --=====================================================================================--
CFile STRUCT
Destructor DWORD ?
OpenFile DWORD ?
CloseFile DWORD ?
Dispose DWORD ?
ConvertToLine DWORD ?
GetLine DWORD ?
EndOfFile WORD ?
handle DWORD ?
ptrHeapText DWORD ?
ptrLine DWORD ?
bytesRead DWORD ?
CFile ENDS
;CFile_initsize equ sizeof CFile
.data
CFile_initdata LABEL BYTE
DWORD OFFSET CFile_Destructor
DWORD OFFSET CFile_OpenFile
DWORD OFFSET CFile_CloseFile
DWORD OFFSET CFile_Dispose
DWORD OFFSET CFile_ConvertToLine
DWORD OFFSET CFile_GetLine
WORD 0
DWORD 0, 0, 0, 0
CFile_initend equ $-CFile_initdata
;UCSTR fileName2, "C:\Users\AlfredoA\Documents\Visual Studio 2015\Projects\SplashScreen\ASM x86\Debug\prueba.txt",0
;UCSTR fileName2, "C:\Users\AlfredoA\Documents\Visual Studio 2015\Projects\SplashScreen\ASM x86\Debug\prueba2.txt",0
fileSize2 LARGE_INTEGER <>
.const
MAXSIZE equ 260
MEMSIZE equ 65535
.data?
SizeReadWrite2 DWORD ? ; number of bytes actually read or write
.code
; --=====================================================================================--
; CLASS CONSTRUCTOR
; --=====================================================================================--
CFile_Init PROC lpTHIS:DWORD
;SET_CLASS CFile
;CFile_initsize equ sizeof CFile
push esi
push edi
push ecx
cld
mov esi, offset CFile_initdata
mov edi, lpTHIS
mov ecx, CFile_initend
shr ecx, 2
rep movsd
mov ecx, CFile_initend
and ecx, 3
rep movsb
mov edi, lpTHIS
assume edi:PTR CFile
;Initialization code
assume edi:nothing
pop ecx
pop edi
pop esi
ret
CFile_Init ENDP
; --=====================================================================================--
; destructor METHOD BEHAVIOR
; --=====================================================================================--
CFile_Destructor PROC uses eax edi lpTHIS:DWORD
mov edi, lpTHIS
assume edi:PTR CFile
mov eax, [edi].handle
.IF eax
invoke CloseHandle, [edi].handle
.ENDIF
mov eax, [edi].ptrHeapText
.IF eax
invoke GlobalFree, [edi].ptrHeapText
.ENDIF
assume edi:nothing
ret
CFile_Destructor ENDP
;--------------------------------------------------------
CFile_OpenFile proc uses eax ebx edi lpTHIS:DWORD, lpszFileName:DWORD
;
; Opens a file, creates a handle and creates a w_char pointer
; Receives: EAX, EBX, ECX, the three integers. May be
; signed or unsigned.
; Returns: EAX = sum, and the status flags (Carry, ; Overflow, etc.) are changed.
; Requires: nothing
;---------------------------------------------------------
; https://stackoverflow.com/questions/56506869/how-to-initialize-a-local-struct-in-masm-assembly
;LOCAL fileSize: LARGE_INTEGER <>
;LOCAL hMemory: DWORD
;LOCAL pMemory: DWORD
;LOCAL pMemoryW: DWORD
;push ebp ; save base pointer
;mov ebp,esp ; base of stack frame
sub esp,8 ; save space for 2 DWORD locals
mov edi, [ebp+8] ; get the parameter passed on the stack to the function
mov edi, lpTHIS ; get the parameter passed on the stack to the function
ASSUME edi:PTR CFile
invoke CreateFile, lpszFileName,\
GENERIC_READ or GENERIC_WRITE ,\
FILE_SHARE_READ or FILE_SHARE_WRITE,\
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,\
NULL
;mov edx, eax
mov [edi].handle, eax
invoke GetFileSizeEx, [edi].handle, ADDR fileSize2
mov eax, fileSize2.LowPart
inc eax ; One bit for the NULL terminated
mov ebx,eax
mov [edi].bytesRead, ebx ; Save the size in the in-memory struct
invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, eax
mov DWORD PTR [ebp-4], eax
invoke GlobalLock, eax
mov DWORD PTR [ebp-8], eax
invoke ReadFile, [edi].handle, DWORD PTR [ebp-8], fileSize2.LowPart, ADDR SizeReadWrite2, NULL
;mov DWORD PTR [ebp-8], eax
invoke CloseHandle, [edi].handle
.IF eax
mov [edi].handle, 0
.ENDIF
mov eax, ebx
shl eax, 1 ;Multiply by 2 in order to convert from char to wchar
invoke GlobalAlloc, GMEM_ZEROINIT, eax
;mov pMemoryW,eax
mov [edi].ptrHeapText, eax
mov [edi].ptrLine, eax
; Convert byte string to word string
invoke MultiByteToWideChar, CP_UTF8, 0, DWORD PTR [ebp-8], -1, [edi].ptrHeapText, 0
;invoke MultiByteToWideChar, CP_UTF8, 0, DWORD PTR [ebp-8], -1, [edi].ptrHeapText, [edi].bytesRead
invoke MultiByteToWideChar, CP_UTF8, 0, DWORD PTR [ebp-8], -1, [edi].ptrHeapText, eax
print [edi].ptrHeapText
;invoke MessageBox, NULL, [edi].ptrHeapText, NULL, MB_OK
invoke GlobalUnlock,DWORD PTR [ebp-8]
invoke GlobalFree,DWORD PTR [ebp-4]
assume edi:nothing
;mov esp, ebp ; Deallocate local variables
;pop ebp ; restore base pointer
ret
CFile_OpenFile endp
; https://stackoverflow.com/questions/51010672/table-with-addresses-or-registers-assembler-x86
;--------------------------------------------------------
CFile_Dispose proc uses edi lpTHIS:DWORD
;
; Opens a file, creates a handle and creates a w_char pointer
; Receives: EAX, EBX, ECX, the three integers. May be
; signed or unsigned.
; Returns: EAX = sum, and the status flags (Carry, ; Overflow, etc.) are changed.
; Requires: nothing
;---------------------------------------------------------
mov edi, lpTHIS
ASSUME edi: PTR CFile
.IF ( [edi].ptrHeapText != 0)
invoke GlobalFree, [edi].ptrHeapText
mov [edi].ptrHeapText, 0
.ENDIF
ASSUME edi: nothing
ret
CFile_Dispose endp
;--------------------------------------------------------
CFile_CloseFile proc lpTHIS:DWORD
;
; Opens a file, creates a handle and creates a w_char pointer
; Receives: EAX, EBX, ECX, the three integers. May be
; signed or unsigned.
; Returns: EAX = sum, and the status flags (Carry, ; Overflow, etc.) are changed.
; Requires: nothing
;---------------------------------------------------------
ret
CFile_CloseFile endp
;--------------------------------------------------------
CFile_ConvertToLine proc uses ax edi esi lpTHIS:DWORD
;
; Opens a file, creates a handle and creates a w_char pointer
; Receives: EAX, EBX, ECX, the three integers. May be
; signed or unsigned.
; Returns: EAX = sum, and the status flags (Carry, ; Overflow, etc.) are changed.
; Requires: nothing
;---------------------------------------------------------
mov edi, lpTHIS ; get the parameter passed on the stack to the function
ASSUME edi:PTR CFile
mov ecx, [edi].bytesRead
mov esi, [edi].ptrHeapText
;shr ecx, 1
loop_ConvertToLine:
mov ax, WORD PTR [esi]
;movzx eax, al
;push ecx
.IF (ax==13)
mov WORD PTR [esi], 0
.ENDIF
;.IF (ax==10)
; mov WORD PTR [esi], 0
;.ENDIF
;print ustr$(eax),32
;print eax
;print chr$(eax)
;pop ecx
add esi, 2
loop loop_ConvertToLine
;print [edi].ptrHeapText, 13, 10
;inkey
ASSUME edi: nothing
ret
CFile_ConvertToLine endp
CFile_GetLine proc uses ecx edi esi lpTHIS:DWORD
mov edi, lpTHIS ; get the parameter passed on the stack to the function
ASSUME edi:PTR CFile
mov esi, [edi].ptrLine
;mov ecx, [edi].ptrHeapText
;sub ecx, esi
;shr ecx, 1
;add ecx, [edi].bytesRead
mov ecx, [edi].bytesRead
shl ecx, 1 ;multiply by 2 since we are using Words for each character
add ecx, [edi].ptrHeapText
sub ecx, esi
shr ecx, 1 ;divide by 2 to get the number of characters
xor eax, eax
; If we are at the beginning of the text, just return the address
.IF esi == [edi].ptrHeapText
mov eax, esi
add esi, 2
jmp exit_GetLine
.ENDIF
iterate:
mov ax, WORD PTR [esi]
.IF (eax==0)
.IF (ecx==1) ;If we are at the end, return NULL
xor eax, eax
.ELSE
add esi, 4 ;Move 2+2 (Chr 13 + chr 10)
mov eax, esi
.ENDIF
jmp exit_GetLine
.ELSE
add esi, 2 ;Move to the next character
.ENDIF
loop iterate
exit_GetLine:
.IF ecx== 1 ;If we are at the end, just reset the Line pointer to the beginning of the text
mov ecx, [edi].ptrHeapText
mov [edi].ptrLine, ecx
.ELSE
mov [edi].ptrLine, esi
.ENDIF
ASSUME edi: nothing
ret
CFile_GetLine endp
ENDIF