1 assembly winapi struct masm calling-convention
我正在尝试使用 Win32 API 和 x64 程序集显示打开的文件对话框。为此,我将预期结构的内存分配与结构的内存分配OPENFILENAMEA
(在commdlg.h
)中进行匹配,但我似乎偏离了 4 个字节,因为我的结构的大小是 140 字节。如果我手动将参数设置为 136 或 152,该CommDlgExtendedError()
函数不会返回(0x0001) ,而是会出现“访问冲突读取位置 0x0000010000007FF7”错误。CDERR_STRUCTSIZE
lStructSize
我ml64.exe
在 Visual Studio 2022 Community 中使用 MASM ( ) 并在 x64 下进行组装。
lpEditInfo
这是我试图匹配(并被lpstrPrompt
省略)的结构: https://learn.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-openfilenamea
typedef struct tagOFNA {
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCSTR lpstrFilter;
LPSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPSTR lpstrFile;
DWORD nMaxFile;
LPSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCSTR lpstrInitialDir;
LPCSTR lpstrTitle;
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCSTR lpstrDefExt;
LPARAM lCustData;
LPOFNHOOKPROC lpfnHook;
LPCSTR lpTemplateName;
LPEDITMENU lpEditInfo;
LPCSTR lpstrPrompt;
void *pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
} OPENFILENAMEA, *LPOPENFILENAMEA;
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
extrn ExitProcess: PROC
extrn GetOpenFileNameA: PROC
extrn CommDlgExtendedError: PROC
.data
filename db 256 dup(0)
tagOFNA STRUCT
lStructSize dd 0 ; 0 - dword
hwndOwner dq 0 ; 4 - qword
hInstance dq 0 ; 12 - qword
lpstrFilter dq 0 ; 20 - qword
lpstrCustomFilter dq 0 ; 28 - qword
nMaxCustFilter dd 0 ; 36 - dword
nFilterIndex dd 0 ; 40 - dword
lpstrFile dq offset filename ; 44 - qword
nMaxFile dd 256 ; 52 - dword
lpstrFileTitle dq 0 ; 56 - qword
nMaxFileTitle dd 0 ; 64 - dword
lpstrInitialDir dq 0 ; 68 - qword
lpstrTitle dq 0 ; 76 - qword
Flags dd 0 ; 84 - dword
nFileOffset dw 0 ; 88 - word
nFileExtension dw 0 ; 90 - word
lpstrDefExt dq 0 ; 92 - qword
lCustData dq 0 ; 100 - qword
lpfnHook dq 0 ; 108 - qword
lpTemplateName dq 0 ; 116 - qword
pvReserved dq 0 ; 124 - qword
dwReserved dd 0 ; 132 - dword
FlagsEx dd 0 ; 136 - dword
tagOFNA ENDS
myofn tagOFNA <sizeof tagOFNA>
.code
main PROC
sub rsp, 28h
lea rcx, myofn
call GetOpenFileNameA
call CommDlgExtendedError
mov rcx, rax
call ExitProcess
main ENDP
end
Run Code Online (Sandbox Code Playgroud)
我尝试为结构设置参数,但这没有任何区别,因此我尝试通过将每个参数设置为 null(除了 和lStructSize
结构lpstrFile
参数)来获取最少量的代码来打开对话框。
正如Peter 所评论的,C 结构体具有用于对齐的填充。您缺少 3 个双字,这使您的大小从预期的 140 变为 152。您必须在 后插入填充lStructSize
,nMaxFile
并将nMaxFileTitle
以下 qword 成员对齐到 8 的倍数:
lStructSize dd 0 ; 0 - dword
pad1 dd 0 ; 4 - dword
hwndOwner dq 0 ; 8 - qword
hInstance dq 0 ; 16 - qword
lpstrFilter dq 0 ; 24 - qword
lpstrCustomFilter dq 0 ; 32 - qword
nMaxCustFilter dd 0 ; 40 - dword
nFilterIndex dd 0 ; 44 - dword
lpstrFile dq offset filename ; 48 - qword
nMaxFile dd 256 ; 56 - dword
pad2 dd 0 ; 60 - dword
lpstrFileTitle dq 0 ; 64 - qword
nMaxFileTitle dd 0 ; 72 - dword
pad3 dd 0 ; 76 - dword
lpstrInitialDir dq 0 ; 80 - qword
lpstrTitle dq 0 ; 88 - qword
Flags dd 0 ; 96 - dword
nFileOffset dw 0 ; 100 - word
nFileExtension dw 0 ; 102 - word
lpstrDefExt dq 0 ; 104 - qword
lCustData dq 0 ; 112 - qword
lpfnHook dq 0 ; 120 - qword
lpTemplateName dq 0 ; 128 - qword
pvReserved dq 0 ; 136 - qword
dwReserved dd 0 ; 144 - dword
FlagsEx dd 0 ; 148 - dword
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
79 次 |
最近记录: |