问题标签 [getoverlappedresult]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
303 浏览

c++ - 为什么 GetOverlappedResult 为 ReadDirectoryChangesW 提供 0 字节结果?

我为我们的项目编写了一个文件系统观察器。突然,它停止正确获取事件。我发现,GetOverlappedResult返回 true 后,结果数据为空,返回的字节数也是空的。

这就是我创建用于观看目录的文件句柄的方式:

这就是我开始观看的方式:

在我使用WaitForMultipleObjects等待事件(不止一个)之后,这就是我尝试获取结果的方式:

但是突然间,当我将文件复制到监视目录时,事件就会触发 - 但我可以在调试器中看到它_ovlBytesReturned0只是_resultData零。

有没有我可以尝试更改的标志来解决这个问题?我很确定它曾经可以工作,我不知道会发生什么变化。

我已经尝试将 false 更改为 true GetOverlappedResult(GetDirectoryHandle(), &_ovl, &_ovlBytesReturned, FALSE),以防有额外的等待需要。它没有任何效果。

0 投票
1 回答
397 浏览

winapi - 使用 GetOverlappedResultEx 中的超时来模拟超时等待?

当使用GetOverlapedResult获取重叠(即异步)I/O 操作的结果时,您可以要求GetOverlappdResult 等待”

这里要注意的部分是 : 的最后一个参数GetOverlappedResultbWait

bWait

如果此参数为TRUE,并且lpOverlapped结构的内部成员为STATUS_PENDING,则该函数在操作完成之前不会返回。如果此参数为FALSE且操作仍处于挂起状态,则函数返回FALSE并且GetLastError函数返回ERROR_IO_INCOMPLETE

对于我的代码,这意味着:

  • 如果 I/O 快速完成,ReadFile返回true
  • 如果 I/O 仍然挂起,那么我等待它完成
  • 如果还有其他错误,我会收到该错误。

这一切都很好。

大多数情况下,这一切都很好

我遇到了实际ReadFile操作需要十分钟才能返回的问题。当它返回时,它返回:

这是这家供应商的存储系统的一个众所周知的问题。.

我想做的是使用 Windows 的异步功能等待 - 但有一个超时。

我注意到GetOverlappedResultEx,它有一种超时参数:

但是当我查看文档时,这是我了解我不理解的 Windows 编程细节的地方 - 排队的 APC,可变等待。但它仍然听起来像我想要的::

dwMilliseconds

超时间隔,以毫秒为单位。

如果dwMilliseconds为零并且操作仍在进行中,则该函数立即返回并且 GetLastError 函数返回 ERROR_IO_INCOMPLETE

如果dwMilliseconds为非零且操作仍在进行中,则该函数将一直等待,直到对象发出信号、I/O 完成例程或 APC 排队,或者在返回之前经过了间隔。使用 GetLastError 获取扩展的错误信息。

如果dwMillisecondsINFINITE,则该函数仅在对象发出信号或 I/O 完成例程或 APC 排队时返回。

所以我尝试改变我的功能:

除了对GetOverlappedResultEx的调用没有在 5 秒(5,000 毫秒)内返回。相反,存储子系统需要 10 到 20 分钟才能恢复故障。

所以我随机尝试

我看到GetOverlappedResultsEx的另一个参数:

听起来不像我的情况:

  • 我没有使用ReadFileEx
  • 我不打电话QueueUserAPC

但这并不一定会阻止我随机尝试事物并希望它们起作用:

但它不起作用。

所以我问 Stackoverflow

我可以使用超时模拟同步操作ReadFile吗?GetOverlappedResultEx

我敢肯定我最终会得到一个涉及消息传递计时器的错误黑客(或者是线程计时器?或者是警报计时器?和事件?和我自己的事件?或者重叠的事件?)。但我宁愿使用好的解决方案而不是我的解决方案。

0 投票
1 回答
432 浏览

c++ - ReadDirectoryChangesW 仅将单个事件放在 FILE_NOTIFY_INFORMATION 缓冲区中

我有一个问题ReadDirectoryChangesW不断丢失事件。

我做了很多谷歌搜索,根据我的搜索,下面的函数参数似乎是正确的,但没有人确切知道。我开始这样看。

完成上述操作后,我等待_ovl.hEventusing WaitForMultipleObjects. 我使用多个对象,因为我总是会告诉监视线程退出的事件。

如果ovl.hEvent收到通知,我会这样做:

在这一点上我应该注意,这info->NextEntryOffset并不总是 0 - 如果我重命名一个文件,我会正确地在 中获得两个条目_resultData,一个用于新文件名,一个用于旧文件名。

永远不会得到的是每个事件的多个文件更改。这是一个问题,整个代码看起来像这样(伪代码)

现在您可以看到我在处理数组ReadDirectoryChangesW 之前重新启动了请求。MyFileInfoStruct但问题是,如果复制了两个以上的文件,第二个文件在我处理前一个文件时被事件注册,但随后的更改被忽略,直到我“拾取”最后一个更改并重新启动事件。

我可以通过让第二个线程来处理来自 FILE_CHANGES部分的所有信息来部分解决这个问题。但这只会通过发出整个启动请求来减少错过事件的机会->等待->拾取->重新启动事件例程更快一些它实际上并没有提供 100% 的覆盖率,仍然存在没有ReadDirectoryChangesW待处理请求的时刻。

我在互联网上阅读了很多内容,发现经常提到两种解决方案:

  • 使用单独的线程来处理文件更改(我已经这样做了)
  • 增加FILE_NOTIFY_INFORMATION[]. 这对我不起作用,Windows 只在那里放置一个事件

因此问题是:我如何获得ReadDirectoryChangesWGetOverlappedResult继续在FILE_NOTIFY_INFORMATION[]缓冲区中添加文件更改,直到我通过调用“拾取”结果GetOverlappedResult?这甚至可能吗?有没有人设法将多个结果放入一个缓冲区?

0 投票
1 回答
84 浏览

winsock2 - WSAGetOverlappedResult 不从套接字返回数据

这是我的代码,我想专注于对WSARecvand的调用WSAGetOverlappedResult

当我运行程序时,它会侦听连接。我与netcat连接。连接后,它按预期打印“接受”。它还会打印“Running GetOverlappedResult”,但即使我在 netcat 上写了很多乱码,“OverlappedResult:”行都不会出现,直到我在 netcat 上按下 Control-C,连接就断开了。然后,我点击了成功分支,它说传输了 0 个字节。

这个程序有什么问题?WSAGetOverlappedResult为什么128 字节缓冲区填满后不返回?

我仔细检查了我对WSARecv和的调用WSAGetOverlappedResult。以下是一些细节:

  • 我将套接字设置为WSARecvto acceptSocket,因为我想从已建立的具体连接中读取。
  • 我将缓冲区计数设置为 1,因为我只有一个缓冲区,而 C 在内存中不区分具有一个元素的数组和只有一个元素。所以我可以将recvBuf用作一个大小的数组。
  • 我设置lpNumberOfBytesRecvd为 null,因为 MSDN 告诉我如果我提供lpOverlapped.
0 投票
0 回答
89 浏览

android - WinUSB,ReadPipe,在 Android 上重叠

希望经常与设备驱动程序打交道的人可以帮助我。我的任务是在不使用 Android 调试桥 (ADB) 的情况下与 Android 设备进行通信。因此,我的发现使我开始使用WinUsb并基本上编写自己的设备驱动程序。现在绊倒/拖了太久,我正在寻求帮助。这是我试图在 C# 而不是 C++ 中完成的,但到目前为止,我已经通过在语言差异之间进行适当转换来完成大部分开发工作。

这是在 C#/WPF 下完成的(而不是使用 .NetCore 或 UWP)

我没有提供源代码作为工作,做的事情,对于那些不工作的事情,我已经尝试了很多不做的迭代,我不想增加任何混淆来影响任何答案。那些知道这些东西很冷的人可能无论如何都不需要它,因为我已经有了通信所需的句柄。

作为一个给定的,使用 ManagementEventWatcher,我能够检测到设备何时与我的设备连接/断开。由此,我能够获取设备信息并读取最终为我提供ENUM\USB\VID_????&PID_????_Interface\GUID DeviceInterface更多信息的设置。

简而言之,函数调用的实际参数仅显示已知方向/意图的上下文,而不是所有实际参数。

从那以后,我可以成功地通过CreateFile( deviceSymbolicName, … )并打开带有 OVERLAPPED 标志的文件(设备)来获得良好的处理,因为文档一直在向我指出。

接下来,我可以调用WinUsb_Initialize()CreateFile()句柄返回的 IntPtr 并获得正确的 WinUSB 句柄。顺便说一句,CreateFile() 和 WinUsb_Initialize() 都返回 IntPtr 句柄。

然后我就可以成功地调用WinUsb_QueryDeviceInformation速度设置,并且工作正常。与WinUsb_QueryInterfaceSettings和相同WinUsb_QueryPipe。从管道信息中,我发现 2 个散装管道分别用于入站和出站。

现在,我正在尝试实际的交流。我从我的研究的其他页面准备了一个请求数据包,以请求代码 0x1001 的 GetDeviceInfo,我获得了成功WinUsb_WritePipe( outboundBulk.PipeId )并获得了 TRUE 返回值。

现在,问题

现在,我有问题。我无法从管道中读取。如果我在没有 Overlapped 标志的情况下打开 CreateFile,则WinUsb_ReadPipe( inboundBulk.PipeId )调用将无限期挂起。当使用 Overlapped 标志时,WinUsb_ReadPipe() 立即返回 true。

所以现在,获取信息是我卡住的地方,我所做的所有阅读都让我扭曲了。

一些代码示例显示我需要执行 ControlTransfers,但我不明白需要什么/何时/为什么。我只是向 WritePipe 索要一些东西,期待并用 ReadPipe 回复。重叠和处理手动重置事件的问题(相对于自动,显然你不能从阅读的东西中使用),但无法弄清楚。此外,必须有某种回调方法,但不知道如何。我的意思是,如果我应该处理手动重置事件,则必须给我某种方式说……嘿,当您完成向我发送数据以使用时调用此方法……对吗?

所以这就是我卡住的地方,并真诚地感谢帮助解决和前进。

评论反馈

最终,我想直接从 PC 复制文件,但必须在没有 Android Debug Bridge 的情况下进行。我需要在我的应用程序用于存储的公共访问文件夹中获取/发送文件......所以,我试图最终学习基本的文件传输等。我不想使用第 3 方实用程序,因为我需要拥有可以针对静态代码分析 (HP Fortify) 运行的完整源代码控制。我看过的大多数其他东西都是基于 java 的,我对此没有经验,更不用说用它编写和理解设备驱动程序了。

虽然对通信的替代方案有点开放,但不确定他们可能会受到我的受限访问要求。