问题标签 [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.
c++ - 为什么 GetOverlappedResult 为 ReadDirectoryChangesW 提供 0 字节结果?
我为我们的项目编写了一个文件系统观察器。突然,它停止正确获取事件。我发现,GetOverlappedResult
返回 true 后,结果数据为空,返回的字节数也是空的。
这就是我创建用于观看目录的文件句柄的方式:
这就是我开始观看的方式:
在我使用WaitForMultipleObjects
等待事件(不止一个)之后,这就是我尝试获取结果的方式:
但是突然间,当我将文件复制到监视目录时,事件就会触发 - 但我可以在调试器中看到它_ovlBytesReturned
也0
只是_resultData
零。
有没有我可以尝试更改的标志来解决这个问题?我很确定它曾经可以工作,我不知道会发生什么变化。
我已经尝试将 false 更改为 true GetOverlappedResult(GetDirectoryHandle(), &_ovl, &_ovlBytesReturned, FALSE)
,以防有额外的等待需要。它没有任何效果。
winapi - 使用 GetOverlappedResultEx 中的超时来模拟超时等待?
当使用GetOverlapedResult获取重叠(即异步)I/O 操作的结果时,您可以要求GetOverlappdResult “等待”:
这里要注意的部分是 : 的最后一个参数GetOverlappedResult
:bWait
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 获取扩展的错误信息。
如果dwMilliseconds为INFINITE,则该函数仅在对象发出信号或 I/O 完成例程或 APC 排队时返回。
所以我尝试改变我的功能:
除了对GetOverlappedResultEx的调用没有在 5 秒(5,000 毫秒)内返回。相反,存储子系统需要 10 到 20 分钟才能恢复故障。
所以我随机尝试
我看到GetOverlappedResultsEx的另一个参数:
这听起来不像我的情况:
- 我没有使用
ReadFileEx
- 我不打电话
QueueUserAPC
但这并不一定会阻止我随机尝试事物并希望它们起作用:
但它不起作用。
所以我问 Stackoverflow
我可以使用超时模拟同步操作ReadFile
吗?GetOverlappedResultEx
我敢肯定我最终会得到一个涉及消息传递计时器的错误黑客(或者是线程计时器?或者是警报计时器?和事件?和我自己的事件?或者重叠的事件?)。但我宁愿使用好的解决方案而不是我的解决方案。
c++ - ReadDirectoryChangesW 仅将单个事件放在 FILE_NOTIFY_INFORMATION 缓冲区中
我有一个问题ReadDirectoryChangesW
不断丢失事件。
我做了很多谷歌搜索,根据我的搜索,下面的函数参数似乎是正确的,但没有人确切知道。我开始这样看。
完成上述操作后,我等待_ovl.hEvent
using WaitForMultipleObjects
. 我使用多个对象,因为我总是会告诉监视线程退出的事件。
如果ovl.hEvent
收到通知,我会这样做:
在这一点上我应该注意,这info->NextEntryOffset
并不总是 0 - 如果我重命名一个文件,我会正确地在 中获得两个条目_resultData
,一个用于新文件名,一个用于旧文件名。
永远不会得到的是每个事件的多个文件更改。这是一个问题,整个代码看起来像这样(伪代码)
现在您可以看到我在处理数组ReadDirectoryChangesW
之前重新启动了请求。MyFileInfoStruct
但问题是,如果复制了两个以上的文件,第二个文件在我处理前一个文件时被事件注册,但随后的更改被忽略,直到我“拾取”最后一个更改并重新启动事件。
我可以通过让第二个线程来处理来自 FILE_CHANGES部分的所有信息来部分解决这个问题。但这只会通过发出整个启动请求来减少错过事件的机会->等待->拾取->重新启动事件例程更快一些它实际上并没有提供 100% 的覆盖率,仍然存在没有ReadDirectoryChangesW
待处理请求的时刻。
我在互联网上阅读了很多内容,发现经常提到两种解决方案:
- 使用单独的线程来处理文件更改(我已经这样做了)
- 增加
FILE_NOTIFY_INFORMATION[]
. 这对我不起作用,Windows 只在那里放置一个事件
因此问题是:我如何获得ReadDirectoryChangesW
并GetOverlappedResult
继续在FILE_NOTIFY_INFORMATION[]
缓冲区中添加文件更改,直到我通过调用“拾取”结果GetOverlappedResult
?这甚至可能吗?有没有人设法将多个结果放入一个缓冲区?
winsock2 - WSAGetOverlappedResult 不从套接字返回数据
这是我的代码,我想专注于对WSARecv
and的调用WSAGetOverlappedResult
:
当我运行程序时,它会侦听连接。我与netcat连接。连接后,它按预期打印“接受”。它还会打印“Running GetOverlappedResult”,但即使我在 netcat 上写了很多乱码,“OverlappedResult:”行都不会出现,直到我在 netcat 上按下 Control-C,连接就断开了。然后,我点击了成功分支,它说传输了 0 个字节。
这个程序有什么问题?WSAGetOverlappedResult
为什么128 字节缓冲区填满后不返回?
我仔细检查了我对WSARecv
和的调用WSAGetOverlappedResult
。以下是一些细节:
- 我将套接字设置为
WSARecv
toacceptSocket
,因为我想从已建立的具体连接中读取。 - 我将缓冲区计数设置为 1,因为我只有一个缓冲区,而 C 在内存中不区分具有一个元素的数组和只有一个元素。所以我可以将
recvBuf
用作一个大小的数组。 - 我设置
lpNumberOfBytesRecvd
为 null,因为 MSDN 告诉我如果我提供lpOverlapped
.
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 的,我对此没有经验,更不用说用它编写和理解设备驱动程序了。
虽然对通信的替代方案有点开放,但不确定他们可能会受到我的受限访问要求。