为什么我的程序集结构的大小与 GetOpenFileNameA 函数期望的结构大小不匹配?

问题描述 投票:0回答:1

我正在尝试使用 win32 api 和 x64 程序集打开一个打开的文件对话框。为此,我将预期结构的内存分配与 OPENFILENAMEA 结构 (commdlg.h) 的内存分配进行匹配,但我似乎偏离了 4 个字节,因为我的结构的大小是 140 个字节,但 CommDlgExtendedError 函数仅不这样做如果我手动将 lStructSize 参数设置为 136 或 152,则不会返回 CDERR_STRUCTSIZE (0x0001)。当我手动将其设置为 136 或 152 时,会发生访问冲突读取位置 0x0000010000007FF7 错误。 我在 Visual Studio 2022 Community 中使用 MASM (ml64.exe) 并在 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;

这是我的代码:

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

我尝试过为结构设置参数,但这没有任何区别,所以我尝试通过将每个参数设置为空(lStructSize 和 lpstrFile 除外)来获取最少量的代码来打开一个打开的文件对话框结构体参数。

assembly winapi struct masm calling-convention
1个回答
0
投票

正如 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    ; 84    - qword
  lpstrTitle        dq 0    ; 92    - qword
  Flags             dd 0    ; 100   - dword
  nFileOffset       dw 0    ; 104   - word
  nFileExtension    dw 0    ; 106   - word
  lpstrDefExt       dq 0    ; 108   - 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
© www.soinside.com 2019 - 2024. All rights reserved.