- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在研究 IO 重定向程序,并成功地为它创建了 poc。该程序生成子进程并使用命名管道与其通信。只要管道上有数据,我就使用 Event 对象来获取事件。默认情况下,我将事件设置为信号状态,但我不是第一次收到该事件。要获得事件,我必须在输入管道上写入。当我在输入管道上写一些命令时,我得到事件并得到旧命令的输出,而不是当前命令(请查看输出)。
下面是工作代码。
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <thread>
#include <string>
using namespace std;
#define input_pipe_name L"\\\\.\\pipe\\input"
#define output_pipe_name L"\\\\.\\pipe\\output"
#define process_name L"cmd.exe"
HANDLE input_pipe_handle;
HANDLE output_pipe_handle;
HANDLE input_file_handle;
HANDLE output_file_handle;
OVERLAPPED output_overlapped = { 0 };
BOOL InitHandels()
{
input_pipe_handle = CreateNamedPipe(input_pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 4096, 4096, 120000, 0);
SetHandleInformation(input_pipe_handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
if (input_pipe_handle == INVALID_HANDLE_VALUE)
{
cout << "pipe creation error: " << GetLastError() << endl;
return FALSE;
}
output_pipe_handle = CreateNamedPipe(output_pipe_name, PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 4096, 4096, 120000, 0);
SetHandleInformation(output_pipe_handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
if (output_pipe_handle == INVALID_HANDLE_VALUE)
{
cout << "pipe creation error: " << GetLastError() << endl;
return FALSE;
}
input_file_handle = CreateFile(input_pipe_name, GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (input_file_handle == INVALID_HANDLE_VALUE)
{
cout << "file creation error: " << GetLastError() << endl;
return FALSE;
}
output_file_handle = CreateFile(output_pipe_name, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (output_file_handle == INVALID_HANDLE_VALUE)
{
cout << "file creation error: " << GetLastError() << endl;
return FALSE;
}
output_overlapped.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
ConnectNamedPipe(output_pipe_handle, &output_overlapped);
}
void CreateChildProcess()
{
TCHAR szCmdline[] = L"cmd.exe";
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = output_pipe_handle;
siStartInfo.hStdOutput = output_pipe_handle;
siStartInfo.hStdInput = input_pipe_handle;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
if (!CreateProcess(NULL, szCmdline, NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo))
{
cout << "process creation error: " << GetLastError() << endl;
//return FALSE;
}
else
{
HANDLE h_array[] = {output_overlapped.hEvent, piProcInfo.hProcess};
for (;;)
{
DWORD result = WaitForMultipleObjects(2, h_array, FALSE, 1000);
DWORD bwritten = 0, bread = 0;
char buffer[4096];
switch (result)
{
case WAIT_TIMEOUT:
//cout << "TimeOut" << endl;
break;
case WAIT_OBJECT_0:
ReadFile(output_file_handle, buffer, sizeof(buffer), &bread, &output_overlapped);
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, bread, &bwritten, 0);
ResetEvent(output_overlapped.hEvent);
break;
case WAIT_OBJECT_0 + 1:
break;
//return FALSE;
}
}
}
}
int main()
{
DWORD bwritten;
InitHandels();
//CreateChildProcess();
std::thread t1(CreateChildProcess);
for (;;Sleep(1000))
{
std::string mystring;
std::cin >> mystring;
mystring.append("\n");
WriteFile(input_file_handle, mystring.c_str(), mystring.length(), &bwritten, &output_overlapped);
//WriteFile(input_file_handle, "dir\n", 4, &bwritten, &output_overlapped);
}
t1.join();
return 0;
}
我得到以下输出
dir
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
D:\Programming\VS\to_post_on_stack\to_post_on_stack>hello
dir
Volume in drive D has no label.
Volume Serial Number is 54FB-7A94
Directory of D:\Programming\VS\to_post_on_stack\to_post_on_stack
01/13/2018 05:36 PM <DIR> .
01/13/2018 05:36 PM <DIR> ..
01/13/2018 05:36 PM <DIR> Debug
01/12/2018 08:54 PM 608 stdafx.cpp
01/12/2018 08:54 PM 642 stdafx.h
01/12/2018 08:54 PM 630 targetver.h
01/13/2018 05:36 PM 7,434 to_post_on_stack.cpp
01/12/2018 08:54 PM 8,038 to_post_on_stack.vcxproj
01/12/2018 08:54 PM 1,277 to_post_on_stack.vcxproj.filters
6 File(s) 18,629 bytes
3 Dir(s) 39,347,019,776 bytes free
D:\Programming\VS\to_post_on_stack\to_post_on_stack>dir
hello
'hello' is not recognized as an internal or external command,
operable program or batch file.
D:\Programming\VS\to_post_on_stack\to_post_on_stack>dir
正如您在发送 dir
命令时的输出中看到的那样,我得到了旧的输出。当我发送 hello
时,我得到了我在 hello
之前执行的 dir
命令的输出。
谁能指出我第一次没有收到信号的错误。为什么输出没有按顺序进行?
最佳答案
充满严重错误的代码示例:
第一个也是主要的:
If hFile was opened with
FILE_FLAG_OVERLAPPED
, the following conditions are in effect:The lpOverlapped parameter must point to a valid and unique
OVERLAPPED
structure, otherwise the function can incorrectly report that the io operation is complete.
和
io operation resets the event specified by the hEvent member of the
OVERLAPPED
structure to a nonsignaled state when it begins the I/O operation. Therefore, the caller does not need to do that.
当 io 操作完成时 - io 子系统写入 lpOverlapped 操作的最终状态、传输的字节数,如果它包含事件 - 将此事件设置为信号状态。如果您在并发中使用相同的 lpOverlapped - 它们会相互覆盖结果,而且您永远不知道 - 哪个操作真正完成 - 事件是一个,常见!,如果您使用事件 - 之前的系统重置事件begin io - 结果 - 一个操作可以完成并设置事件,然后另一个操作在此之后重置它
你同时调用了 2 个线程:
WriteFile(input_file_handle, ..&output_overlapped);
ReadFile(output_file_handle, .. &output_overlapped);
有了这个,你已经有了 UB,因为并发使用了相同的 &output_overlapped
。我们需要为每个操作分配唯一的重叠。如果您使用事件来检测完成 - 您需要创建多个事件 - 这根本不是好方法。最好在这里使用 iocp 完成 - 我们不需要创建事件,我们不需要创建单独的线程。
ReadFile(output_file_handle, buffer, sizeof(buffer), &bread, &output_overlapped);
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, bread, &bwritten, 0);
ResetEvent(output_overlapped.hEvent);
首先 ReadFile
在开始 I/O 时将 OVERLAPPED
结构的 hEvent
成员指定的事件重置为无信号状态手术。因此,调用者不需要这样做。以及更多 - 当您调用 ResetEvent
- 操作可能已经完成 - 因此您重置已经发出信号的事件 - 结果您丢失了完成信号。如果调用 ReasetEvent
这需要执行 before io 操作(在具体情况下为 ReadFile
)而不是 after - 这是错误.然而我们不需要这样做和之前 - 因为 io 子系统无论如何都会这样做。
还有一个严重错误 - 我们不能在 WriteFile
中使用 buffer, bread
就在 asynchronous 调用 ReadFile
之后> - 调用尚未完成。和 buffer
的上下文尚未定义。
&bread
在异步调用中总是未定义,根本不能使用
The lpNumberOfBytesRead parameter should be set to NULL. Use the
GetOverlappedResult
function to get the actual number of bytes read. If the hFile parameter is associated with an I/O completion port, you can also get the number of bytes read by calling the GetQueuedCompletionStatus function.
还有一个非常常见的错误 - 我们创建了 2 管道对(input_pipe_handle
, output_file_handle
) - 这绝对不需要 - 我们可以使用 1 管道对。
对 SetHandleInformation
的调用过多 - 我们只需要通过 SECURITY_ATTRIBUTES
创建具有继承属性的句柄。
代码示例:
//#define _XP_SUPPORT_
struct IO_COUNT
{
HANDLE _hFile;
HANDLE _hEvent;
LONG _dwIoCount;
IO_COUNT()
{
_dwIoCount = 1;
_hEvent = 0;
}
~IO_COUNT()
{
if (_hEvent)
{
CloseHandle(_hEvent);
}
}
ULONG Create(HANDLE hFile);
void BeginIo()
{
InterlockedIncrement(&_dwIoCount);
}
void EndIo()
{
if (!InterlockedDecrement(&_dwIoCount))
{
SetEvent(_hEvent);
}
}
void Wait()
{
WaitForSingleObject(_hEvent, INFINITE);
}
};
class U_IRP : OVERLAPPED
{
enum { connect, read, write };
IO_COUNT* _pIoObject;
ULONG _code;
LONG _dwRef;
char _buffer[256];
~U_IRP()
{
_pIoObject->EndIo();
}
ULONG Read()
{
_code = read;
AddRef();
return CheckIoResult(ReadFile(_pIoObject->_hFile, _buffer, sizeof(_buffer), 0, this));
}
ULONG CheckIoResult(BOOL fOk)
{
if (fOk)
{
#ifndef _XP_SUPPORT_
OnIoComplete(NOERROR, InternalHigh);
#endif
return NOERROR;
}
ULONG dwErrorCode = GetLastError();
if (dwErrorCode != ERROR_IO_PENDING)
{
OnIoComplete(dwErrorCode, 0);
}
return dwErrorCode;
}
VOID OnIoComplete(DWORD dwErrorCode, DWORD_PTR dwNumberOfBytesTransfered)
{
switch (_code)
{
case connect:
switch (dwErrorCode)
{
case ERROR_PIPE_CONNECTED:
case ERROR_NO_DATA:
dwErrorCode = NOERROR;
case NOERROR:
Read();
}
break;
case read:
if (dwErrorCode == NOERROR)
{
if (dwNumberOfBytesTransfered)
{
if (int cchWideChar = MultiByteToWideChar(CP_OEMCP, 0, _buffer, (ULONG)dwNumberOfBytesTransfered, 0, 0))
{
PWSTR wz = (PWSTR)alloca(cchWideChar * sizeof(WCHAR));
if (MultiByteToWideChar(CP_OEMCP, 0, _buffer, (ULONG)dwNumberOfBytesTransfered, wz, cchWideChar))
{
if (int cbMultiByte = WideCharToMultiByte(CP_ACP, 0, wz, cchWideChar, 0, 0, 0, 0))
{
PSTR sz = (PSTR)alloca(cbMultiByte);
if (WideCharToMultiByte(CP_ACP, 0, wz, cchWideChar, sz, cbMultiByte, 0, 0))
{
DbgPrint("%.*s", cbMultiByte, sz);
}
}
}
}
}
Read();
}
break;
case write:
break;
default:
__debugbreak();
}
Release();
if (dwErrorCode)
{
DbgPrint("[%u]: error=%u\n", _code, dwErrorCode);
}
}
static VOID WINAPI _OnIoComplete(
DWORD dwErrorCode,
DWORD dwNumberOfBytesTransfered,
LPOVERLAPPED lpOverlapped
)
{
static_cast<U_IRP*>(lpOverlapped)->OnIoComplete(RtlNtStatusToDosError(dwErrorCode), dwNumberOfBytesTransfered);
}
public:
void AddRef()
{
InterlockedIncrement(&_dwRef);
}
void Release()
{
if (!InterlockedDecrement(&_dwRef)) delete this;
}
U_IRP(IO_COUNT* pIoObject) : _pIoObject(pIoObject)
{
_dwRef = 1;
pIoObject->BeginIo();
RtlZeroMemory(static_cast<OVERLAPPED*>(this), sizeof(OVERLAPPED));
}
ULONG Write(const void* pvBuffer, ULONG cbBuffer)
{
_code = write;
AddRef();
return CheckIoResult(WriteFile(_pIoObject->_hFile, pvBuffer, cbBuffer, 0, this));
}
ULONG Connect()
{
_code = connect;
AddRef();
return CheckIoResult(ConnectNamedPipe(_pIoObject->_hFile, this));
}
static ULONG Bind(HANDLE hFile)
{
return BindIoCompletionCallback(hFile, U_IRP::_OnIoComplete, 0)
#ifndef _XP_SUPPORT_
&& SetFileCompletionNotificationModes(hFile, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)
#endif
? NOERROR : GetLastError();
}
};
ULONG IO_COUNT::Create(HANDLE hFile)
{
_hFile = hFile;
if (_hEvent = CreateEvent(0, TRUE, FALSE, 0))
{
return U_IRP::Bind(hFile);
}
return GetLastError();
}
void ChildTest()
{
static const WCHAR name[] = L"\\\\?\\pipe\\somename";
HANDLE hFile = CreateNamedPipeW(name,
PIPE_ACCESS_DUPLEX|FILE_READ_DATA|FILE_WRITE_DATA|FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE|PIPE_READMODE_BYTE, 1, 0, 0, NMPWAIT_USE_DEFAULT_WAIT, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
IO_COUNT obj;
if (obj.Create(hFile) == NOERROR)
{
BOOL fOk = FALSE;
static SECURITY_ATTRIBUTES sa = { sizeof(sa), 0, TRUE };
STARTUPINFOW si = { sizeof(si) };
PROCESS_INFORMATION pi;
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdError = CreateFileW(name, FILE_GENERIC_READ|FILE_GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 0, 0);
if (si.hStdError != INVALID_HANDLE_VALUE)
{
si.hStdInput = si.hStdOutput = si.hStdError;
WCHAR ApplicationName[MAX_PATH];
if (GetEnvironmentVariableW(L"ComSpec", ApplicationName, RTL_NUMBER_OF(ApplicationName)))
{
if (CreateProcessW(ApplicationName , 0, 0, 0, TRUE, 0, 0, 0, &si, &pi))
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
fOk = TRUE;
}
}
CloseHandle(si.hStdError);
}
if (fOk)
{
U_IRP* p;
if (p = new U_IRP(&obj))
{
p->Connect();
p->Release();
}
obj.EndIo();
//++ simulate user commands
static PCSTR commands[] = { "dir\r\n", "ver\r\n", "exit\r\n" };
ULONG n = RTL_NUMBER_OF(commands);
PCSTR* psz = commands;
do
{
if (p = new U_IRP(&obj))
{
PCSTR command = *psz++;
p->Write(command, (ULONG)strlen(command) * sizeof(CHAR));
p->Release();
}
} while (--n);
//--
obj.Wait();
}
}
CloseHandle(hFile);
}
}
关于c++ - CreateEvent 初始状态信号不是信号事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48239819/
我正在研究 IO 重定向程序,并成功地为它创建了 poc。该程序生成子进程并使用命名管道与其通信。只要管道上有数据,我就使用 Event 对象来获取事件。默认情况下,我将事件设置为信号状态,但我不是第
我正在开发一个自动化项目,我试图单击网站上的按钮。我已设法识别该元素,但当我尝试使用 document.createEvent 时,它告诉我该对象不支持它。有什么想法吗? function categ
我正在尝试在 Web 应用程序中模拟按键,它适用于嵌入式系统,但它使用 Webkit 派生浏览器。我在 Chrome 中测试了代码并得到了同样的错误。 我尝试使用来自 Yahoo 的示例中的代码片段,
我有一个场景,我有一些文本,应该是用户可选择的。问题是,它上面有一个 UI 覆盖层,默认情况下会阻止选择文本。保留叠加层并仍然能够选择文本的合乎逻辑的方法是使用合成事件(使用 document.cre
以下代码失败(在 javascript 控制台中,以及通过浏览器扩展注入(inject)脚本时) document.createEvent('TestEvent') Firebug 吐出: [Exce
这个问题在这里已经有了答案: Not able to create event on Calendar with this script (2 个答案) 关闭 7 个月前。 我一直在编写代码,以便在
我有来自 here 的以下脚本: function download(filename, text) { var pom = document.createElement('a');
我正在使用找到的自定义输入事件@ http://whattheheadsaid.com/projects/input-special-event. . 问题是我无法获取该事件的 key 代码。有什么想
我有一个 process-1 尝试使用以下方式打开事件: LPCWSTR a = L"ShellReadyEvent"; HANDLE hEvent = OpenEvent ( EVENT_ALL_A
我在检查某人的代码时看到了这个: template class ConcurrentQueue { private: HANDLE dataPushEvent;
我很好奇在 Quake 中使用 CreateEvent() 函数。 我们在 WinMain() 定义的 c 文件中有以下全局变量: static HANDLE tevent; 在 WinMain()
如果我使用 CreateEvent 打开一个事件: responseWaitEvent = CreateEvent(NULL, // no security TRUE,
本文整理了Java中facebook4j.internal.json.z_F4JInternalFactory.createEvent()方法的一些代码示例,展示了z_F4JInternalFacto
这个问题已经有答案了: How to merge date and time as a datetime in Google Apps Spreadsheet script? (1 个回答) 已关闭
我们正在尝试使用 Google 表单创建一个在线表单来接受预约请求。这个过程应该是这样的: 用户填写表格并提交他们的信息(有效) 一封电子邮件被发送到我们的 Gmail 以通知我们有新的传入请求(这有
我正在编写一个 ant-cheat Win32 加载程序,我需要在其中创建一个事件,等待它收到我存储它的另一个进程的信号 - 但它因 ERROR_INVALID_HANDLE 而失败。我正在创建一个未
如果我在 Visual Studio 2005 中编译以下函数,我会遇到几个编译错误: void search() { deviceEventHandle = CreateEvent(NULL
我的 Windows 服务使用 CreateEvent 创建了 2 个事件,用于与用户应用程序通信。该服务和用户应用程序未在同一用户帐户下运行。用户应用程序打开事件并将其设置为无错误地发出信号。但是该
我试图模拟被拒绝的值并得到这个错误。奇怪的是,这种构造在“成功”的情况下有效addUser.mockImplementation(value => jest.fn().mockResolvedValu
我正在寻找 Mac OS X 上最简单或最合适的方法来简单地“发出信号”或通知一个进程。来自 Windows 背景,这可以使用类似以下的方法来实现。 进程A: // create named even
我是一名优秀的程序员,十分优秀!