我正在阅读有关CreateTimerQueueTimer的手册页。
BOOL CreateTimerQueueTimer(
  PHANDLE             phNewTimer,
  HANDLE              TimerQueue,
  WAITORTIMERCALLBACK Callback,
  PVOID               DueTime,
  DWORD               Period,
  DWORD               Flags,
  ULONG               Parameter
);

文档状态:

周期
计时器的周期(以毫秒为单位)。如果此参数为零,则计时器会发出一次信号。

所以我需要将其设置为0,以避免定期执行回调。
问题是修改period值有对周期性没有影响。加载到OllyDBG中后,Olly重构了参数和给我此函数签名的调用:
BOOL CreateTimerQueueTimer(
 PHANDLE             phNewTimer,
 HANDLE              TimerQueue,
 WAITORTIMERCALLBACK Callback,
 ULONG               Parameter,
 PVOID               DueTime,
 DWORD               Period,
 DWORD               Flags
);

请注意,parameter参数更改了位置,因此我所有的补丁都没有用。我猜这个错误可能是由于API的旧版本导致Parameter参数位于第4位,但我可能是错的。另外,我找不到旧的WinAPI来确认我的说法。
我猜对了还是错过了什么?

#1 楼

是的,我想我以前也看过类似的案例。这种情况很少发生,但是由于您可以在C预处理程序级别和链接程序级别上进行一些特技,因此这种情况确实有效。

在这种情况下,我在3790.1830 DDK中进行了查找( Windows 2003 Server)和一些较新的WDK和SDK。

Windows 2000 / XP目标(3790.1830/inc/w2k/winbase.h3790.1830/inc/wxp/winbase.h

WINBASEAPI
BOOL
WINAPI
CreateTimerQueueTimer(
    PHANDLE phNewTimer,
    HANDLE TimerQueue,
    WAITORTIMERCALLBACK Callback,
    PVOID Parameter,
    DWORD DueTime,
    DWORD Period,
    ULONG Flags
    ) ;  


Windows 2003 / Vista / 7目标(3790.1830/inc/wnet/winbase.h6001.18002/inc/api/WINBASE.H7600.16385.1/inc/api/WINBASE.H

WINBASEAPI
BOOL
WINAPI
CreateTimerQueueTimer(                                                                                                                                                                                             
    __deref_out PHANDLE phNewTimer,
    __in_opt    HANDLE TimerQueue,
    __in        WAITORTIMERCALLBACK Callback,
    __in_opt    PVOID Parameter,
    __in        DWORD DueTime,
    __in        DWORD Period,
    __in        ULONG Flags 
    ) ;   


使用Windows 8.1 SDK ...

...此API已移入另一个标头:Include/um/threadpoollegacyapiset.h(请参阅有关API集的研究)。

WINBASEAPI
BOOL
WINAPI
CreateTimerQueueTimer(
    _Outptr_ PHANDLE phNewTimer,
    _In_opt_ HANDLE TimerQueue,
    _In_ WAITORTIMERCALLBACK Callback,
    _In_opt_ PVOID Parameter,
    _In_ DWORD DueTime,
    _In_ DWORD Period,
    _In_ ULONG Flags
    );  


...所以直到这一点为止都没有改变(除了采用SAL2注释)。

对于Windows 10 SDK 10.0.10240.0、10.0.16299.0、10.0.17134.0、10.0.17134.0、10.0.17763.0、10.0.18362.0,其参数顺序与Windows 8.1相同。因此,这是您遇到文档问题而不是实际更改的原因。
没有提及此功能的挂起或旧的(和已关闭的)拉取请求,因此您可能要考虑发送一个。

评论


谢谢,有没有参考该API旧版本的资源?在backbackmachine上找不到它们!

–黑暗
19/12/24在1:34

@Nark不确定要表达的意思,因为-正如他们所说-代码没有说谎。正如我向您指出的那样,至少从Windows 2000以来,标头显示的参数顺序相同。新的子域将不在Internet存档中,并且通常MS更改了URL,所以如果您设法找到URL,我通常会认为您很幸运一。如果需要验证我的发现,为什么不与Windows 7 SDK或更旧的版本进行交叉检查呢?

– 0xC0000022L♦
19/12/24在20:22

所以如果我做对的话,这是一个链接程序/编译器问题?

–黑暗
19/12/25在14:39