I have to call WinApi SHFileOperationW function, but before this I need to fill this struct
typedef struct _SHFILEOPSTRUCTW {
HWND hwnd;
UINT wFunc;
PCZZWSTR pFrom;
PCZZWSTR pTo;
FILEOP_FLAGS fFlags;
BOOL fAnyOperationsAborted;
LPVOID hNameMappings;
PCWSTR lpszProgressTitle;
} SHFILEOPSTRUCTW, *LPSHFILEOPSTRUCTW;
In MASM I defined this like that:
SHFILEOPSTRUCT struct
hwnd dq ?
wFunc dd ?
pFrom dq ?
pTo dq ?
fFlags dw ?
fAnyOperationsAborted dd ?
hNameMappings dq ?
lpszProgressTitle dq ?
SHFILEOPSTRUCT ends
In .data section I init my struct:
fos SHFILEOPSTRUCT <?>
So when I filling my struct with mov operations and load the address in rcx(1 arg of function) it cause error, but if I push struct fields in the stack and pass to function RSP its work just fine. Why so? Need I fill all the fields even if it 0? (does not work ↓)
mov [fos.hwnd], 0 ; hWnd
mov [fos.wFunc], FO_DELETE ; Delete
mov rax, offset filename
mov [fos.pFrom], rax ; Filename
mov [fos.fFlags], FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT
lea rcx, fos
vs (it's work ↓)
push 0
push 0
push 0
push FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT
push 0
pushaddr filename
push FO_DELETE
push 0
mov rcx, rsp
And then ofc I allocate some space in the stack and call the func:
sub rsp, 28h
call SHFileOperationW
CodePudding user response:
The C/C headers in the Windows SDK assume the platform's default alignment is used.
this controlled by /Zp (Struct Member Alignment) option in both msvc and ML/ML64 ( The alignment can be 1, 2, 4, 8 or 16)
look also How align works with data packing
difference betweem MSVC and ML64: MSVC use /Zp16 as default for x64 and ARM64 but ML64 not.
so you need or direct set /Zp16 in ML64 command line (the best) or direct set aligment in STRUCT
declaration:
like SHFILEOPSTRUCTW struct 16
also declare variable In .data section - mean use global variable and bad solution. this must be local variable, so in stack. code can look like
.code
SHFILEOPSTRUCTW struct 16
hwnd dq ?
wFunc dd ?
pFrom dq ?
pTo dq ?
fFlags dw ?
fAnyOperationsAborted dd ?
hNameMappings dq ?
lpszProgressTitle dq ?
SHFILEOPSTRUCTW ends
FO_DELETE EQU 03h
FOF_NOCONFIRMATION EQU 10h
FOF_ALLOWUNDO EQU 40h
FOF_SILENT EQU 04h
EXTERN __imp_SHFileOperationW:QWORD
VarSize EQU ((SIZEOF SHFILEOPSTRUCTW 15) and not 15)
fos EQU [rsp 20h]
er_ff proc
sub rsp, 28h VarSize
xor eax,eax
mov fos[SHFILEOPSTRUCTW.hwnd],rax
mov fos[SHFILEOPSTRUCTW.wFunc],FO_DELETE
mov fos[SHFILEOPSTRUCTW.pFrom],rcx
mov fos[SHFILEOPSTRUCTW.pTo],rax
mov fos[SHFILEOPSTRUCTW.fFlags],FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT
lea rcx,fos
call __imp_SHFileOperationW
add rsp, 28h VarSize
ret
er_ff endp
end
so use SHFILEOPSTRUCTW struct 16
ot better ml64 /c /Cp /Zp16 "$(InputFileName)"