I'm trying to write to a com port that my Arduino micro is plugged into. All its doing is trying to send an int at a time. I have the serial monitor open in Arduino bound to that port and I'm able to send bytes to it (I have a print line to show its receiving bytes) but when I use the CPP impl - I get nothing. I'm new to this so may have missed something out but I dont even get any errors.
Any help?
`
Arduino::~Arduino()
{
CloseHandle(hSerial);
}
void Arduino::send(int x, int y, int a)
{
std::cout << "Sending these values = " << x << y << a << std::endl;
if (!WriteFile(hSerial, &x, 1, NULL, NULL)) {
DWORD lastError = GetLastError();
std::cout << "ERROR HERE SENDING X! = " << lastError << std::endl;
}
else {
std::cout << "Sent X" << std::endl;
}
if (!WriteFile(hSerial, &y, 1, NULL, NULL)) {
DWORD lastError = GetLastError();
std::cout << "ERROR HERE SENDING Y! = " << lastError << std::endl;
}
else {
std::cout << "Sent Y" << std::endl;
}
if (!WriteFile(hSerial, &a, 1, NULL, NULL)) {
DWORD lastError = GetLastError();
std::cout << "ERROR HERE SENDING A! = " << lastError << std::endl;
}
else {
std::cout << "Sent A" << std::endl;
}
}
void Arduino::mouseEvent(int x, int y, int click)
{
send(x, y, click);
}
void Arduino::Init(std::wstring comport)
{
hSerial = CreateFile(comport.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hSerial == INVALID_HANDLE_VALUE)
{
DWORD lastError = GetLastError();
std::cout << "ERROR HERE! = " << lastError << std::endl;
}
DCB dcbSerialParams = { 0 };
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
GetCommState(hSerial, &dcbSerialParams);
dcbSerialParams.BaudRate = CBR_115200;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
SetCommState(hSerial, &dcbSerialParams);
}
`
I'm expecting, at the very least, to get a println in my Arduino IDE to say that the board has received bytes when I hit the .Send() but I get nothing. I know the Arduino code works fine as I'm able to use the IDE to send bytes to decode then perform operations on.
Related
I wrote a simple inter-process communication with a memory-mapped file. The code works relatively well, but I have a problem with the buffer that I'll explain shortly. Here is the code (C++, Windows):
#define UNICODE
#define _UNICODE
#include <iostream>
#include <tchar.h>
#include <Windows.h>
int wmain(int argc, wchar_t** argv)
{
if (argc != 2)
{
std::cout << "Usage: `win32mmap w` for writing, or `win32mmap r` for reading.\n";
return -1;
}
HANDLE hMapFile;
HANDLE hEvent;
HANDLE isOpened = CreateEvent(NULL, true, false, L"IsOpened"); // To check if a `win32mmap w` runs
if (wcscmp(argv[1], L"w") == 0)
{
SetEvent(isOpened);
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 1024, L"mmapFile");
if (hMapFile == NULL)
{
std::cout << "CreateFileMapping() Error: " << GetLastError() << "\n";
return GetLastError();
}
hEvent = CreateEvent(NULL, true, false, L"mmapEvent");
if (hEvent == INVALID_HANDLE_VALUE || hEvent == NULL)
{
std::cout << "CreateEvent() Error: " << GetLastError() << "\n";
return GetLastError();
}
char* buff = (char*)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 0);
if (!buff)
{
std::cout << "MapViewOfFile() Error: " << GetLastError() << "\n";
return GetLastError();
}
while (buff[0] != L'.')
{
std::cin >> buff;
SetEvent(hEvent);
}
UnmapViewOfFile(buff);
}
else if (wcscmp(argv[1], L"r") == 0)
{
if (WaitForSingleObject(isOpened, 0) == WAIT_TIMEOUT)
{
std::cout << "Waiting for `win32mmap w`...";
WaitForSingleObject(isOpened, INFINITE);
std::cout << "\n";
}
hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, L"mmapFile");
if (hMapFile == NULL)
{
std::cout << "CreateFileMapping() Error: " << GetLastError() << "\n";
return GetLastError();
}
hEvent = OpenEvent(EVENT_ALL_ACCESS, false, L"mmapEvent");
if (hEvent == INVALID_HANDLE_VALUE || hEvent == NULL)
{
std::cout << "CreateFile() Error: " << GetLastError() << "\n";
return GetLastError();
}
char* buff = (char*)MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
if (!buff)
{
std::cout << "MapViewOfFile() Error: " << GetLastError() << "\n";
return GetLastError();
}
if (!buff)
{
std::cout << "MapViewOfFile() Error: " << GetLastError() << "\n";
return GetLastError();
}
while (true)
{
WaitForSingleObject(hEvent, INFINITE);
ResetEvent(hEvent);
if (buff[0] == '.')
{
break;
}
std::cout << buff << "\n";
}
UnmapViewOfFile(buff);
}
else
{
std::cout << "Usage: `win32mmap w` for writing, or `win32mmap r` for reading.\n";
return -1;
}
CloseHandle(hMapFile);
return 0;
}
The program is a simple inter-process communication "chat" that relies on memory-mapped files. To use the program, you need to make two executable instance of the program: win32mmap w and win32mmap r. The first instance is used to type text that is displayed in the second instance. When you type . in the first instance, both of them are terminated.
My problem is when I run the 2 instances of the program, and I type the world Hello in the first instance (win32mmap w), the second instance shows Hello as expected. But when I type Hello World in the first instance, the second instance shows only the word World instead of Hello World. How can I fix the code that the buffer will get the whole text?
Your writer is not waiting for the reader to consume the data before overwriting it with new data.
You need 2 events - one for the reader to wait on signaling when the buffer has data to read, and one for the writer to wait on signaling when the buffer needs data.
Try this instead:
#define UNICODE
#define _UNICODE
#include <iostream>
#include <tchar.h>
#include <Windows.h>
const DWORD BufSize = 1024;
int wmain(int argc, wchar_t** argv)
{
if (argc != 2)
{
std::cout << "Usage: `win32mmap w` for writing, or `win32mmap r` for reading.\n";
return -1;
}
HANDLE hMapFile;
char* buff;
HANDLE hNeedDataEvent;
HANDLE hHasDataEvent;
DWORD dwError;
HANDLE isOpened = CreateEvent(NULL, TRUE, FALSE, L"IsOpened"); // To check if a `win32mmap w` runs
if (isOpened == NULL)
{
dwError = GetLastError();
std::cout << "CreateEvent() Error: " << dwError << "\n";
return dwError;
}
if (wcscmp(argv[1], L"w") == 0)
{
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, BufSize, L"mmapFile");
if (hMapFile == NULL)
{
dwError = GetLastError();
std::cout << "CreateFileMapping() Error: " << dwError << "\n";
SetEvent(isOpened);
return dwError;
}
buff = (char*) MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, BufSize);
if (!buff)
{
dwError = GetLastError();
std::cout << "MapViewOfFile() Error: " << dwError << "\n";
SetEvent(isOpened);
return dwError;
}
hNeedDataEvent = CreateEvent(NULL, TRUE, TRUE, L"mmapNeedDataEvent");
if (hNeedDataEvent == NULL)
{
dwError = GetLastError();
std::cout << "CreateEvent() Error: " << dwError << "\n";
SetEvent(isOpened);
return dwError;
}
hHasDataEvent = CreateEvent(NULL, TRUE, FALSE, L"mmapHasDataEvent");
if (hHasDataEvent == NULL)
{
dwError = GetLastError();
std::cout << "CreateEvent() Error: " << dwError << "\n";
SetEvent(isOpened);
return dwError;
}
SetEvent(isOpened);
while (WaitForSingleObject(hNeedDataEvent, INFINITE) == WAIT_OBJECT_0)
{
std::cin.get(buff, BufSize);
ResetEvent(hNeedDataEvent);
SetEvent(hHasDataEvent);
if (buff[0] == L'.') break;
}
}
else if (wcscmp(argv[1], L"r") == 0)
{
if (WaitForSingleObject(isOpened, 0) == WAIT_TIMEOUT)
{
std::cout << "Waiting for `win32mmap w`...";
WaitForSingleObject(isOpened, INFINITE);
std::cout << "\n";
}
hMapFile = OpenFileMapping(FILE_MAP_READ, FALSE, L"mmapFile");
if (hMapFile == NULL)
{
dwError = GetLastError();
std::cout << "CreateFileMapping() Error: " << dwError << "\n";
return dwError;
}
char* buff = (char*) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, BufSize);
if (!buff)
{
dwError = GetLastError();
std::cout << "MapViewOfFile() Error: " << dwError << "\n";
return dwError;
}
hNeedDataEvent = OpenEvent(SYNCHRONIZE, FALSE, L"mmapNeedDataEvent");
if (hNeedDataEvent == NULL)
{
dwError = GetLastError();
std::cout << "OpenEvent() Error: " << dwError << "\n";
return dwError;
}
hHasDataEvent = OpenEvent(SYNCHRONIZE, FALSE, L"mmapHasDataEvent");
if (hHasDataEvent == NULL)
{
dwError = GetLastError();
std::cout << "OpenEvent() Error: " << dwError << "\n";
return dwError;
}
do
{
SetEvent(hNeedDataEvent);
if (WaitForSingleObject(hHasDataEvent, INFINITE) != WAIT_OBJECT_0)
break;
std::cout << buff << "\n";
ResetEvent(hHasDataEvent);
}
while (buff[0] != '.');
}
else
{
std::cout << "Usage: `win32mmap w` for writing, or `win32mmap r` for reading.\n";
return -1;
}
UnmapViewOfFile(buff);
CloseHandle(hMapFile);
CloseHandle(hNeedDataEvent);
CloseHandle(hHasDataEvent);
CloseHandle(isOpened);
return 0;
}
I was trying to inject a shared library in another process and I managed to get it working on x64. Though, when I tried using it for 32bits, something weird is happening: ptrace is not being able to execute properly due to an Input/Output error (errno 5). I don't know what to do, since this same code worked for x64.
Then, I tried to make a smaller example using a function that I called test_ptrace. Surprisingly, the error doesn't happen there, though it is doing essentially the same thing (allocate memory on target process, inject a payload, set registers to match the payload, run the payload). When I saw the error was not happening, I tried again injecting the shared library with ptrace using a function called load_library. But unfortunately, there the error was again.
//this is the function that is NOT working, 'load_library'
void* load_library(pid_t pid, std::string path, int mode)
{
int status;
struct user_regs_struct old_regs, regs;
void* dlopen_ex = (void*)0xf7c29700; //I disabled ASLR, so this address does not change
void* handle_ex = (void*)-1;
unsigned char inj_buf[] =
{
0x51, //push ecx
0x53, //push ebx
0xFF, 0xD0, //call eax
0xCC, //int3 (SIGTRAP)
};
size_t path_size = path.size();
size_t inj_size = sizeof(inj_buf) + path_size;
void* inj_addr = allocate_memory(pid, inj_size, PROT_EXEC | PROT_READ | PROT_WRITE);
void* path_addr = (void*)((uintptr_t)inj_addr + sizeof(inj_buf));
write_memory(pid, inj_addr, (void*)inj_buf, sizeof(inj_buf));
write_memory(pid, path_addr, (void*)path.c_str(), path_size);
if(ptrace(PTRACE_ATTACH, pid, NULL, NULL))
{
perror("PTRACE_ATTACH");
std::cout << "Errno: " << errno << std::endl;
return handle_ex;
}
wait(&status);
if(ptrace(PTRACE_GETREGS, pid, NULL, &old_regs) == -1)
{
perror("PTRACE_GETREGS");
std::cout << "Errno: " << errno << std::endl;
return handle_ex;
}
regs.eax = (unsigned long)dlopen_ex;
regs.ebx = (unsigned long)path_addr;
regs.ecx = (unsigned long)mode;
regs.eip = (unsigned long)inj_addr;
if(ptrace(PTRACE_SETREGS, pid, NULL, ®s) == -1)
{
perror("PTRACE_SETREGS");
std::cout << "Errno: " << errno << std::endl;
return handle_ex;
}
if(ptrace(PTRACE_CONT, pid, NULL, NULL) == -1)
{
perror("PTRACE_CONT");
std::cout << "Errno: " << errno << std::endl;
return handle_ex;
}
waitpid(pid, &status, WSTOPPED);
if(ptrace(PTRACE_GETREGS, pid, NULL, ®s) == -1)
{
perror("PTRACE_GETREGS");
std::cout << "Errno: " << errno << std::endl;
return handle_ex;
}
handle_ex = (void*)old_regs.eax;
if(ptrace(PTRACE_SETREGS, pid, NULL, &old_regs) == -1)
{
perror("PTRACE_SETREGS");
std::cout << "Errno: " << errno << std::endl;
return handle_ex;
}
if(ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1)
{
perror("PTRACE_DETACH");
std::cout << "Errno: " << errno << std::endl;
return handle_ex;
}
deallocate_memory(pid, inj_addr, inj_size);
return handle_ex;
}
//this one, though, is working, but it is very similar to the function
//above (except it doesn't restore the execution, but the code of the
//other function doesn't even get there anyway.
void test_ptrace(pid_t pid)
{
int status;
struct user_regs_struct regs;
unsigned char inj_buf[] =
{
0xCD, 0x80, //int80 (syscall)
0xCC, //int3 (SIGTRAP)
};
void* inj_addr = allocate_memory(pid, sizeof(inj_buf), PROT_EXEC | PROT_READ | PROT_WRITE);
write_memory(pid, inj_addr, inj_buf, sizeof(inj_buf));
std::cout << "--ptrace test started--" << std::endl;
if(ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1)
{
perror("PTRACE_ATTACH");
std::cout << "Errno: " << errno << std::endl;
return;
}
wait(&status);
if(ptrace(PTRACE_GETREGS, pid, NULL, ®s) == -1)
{
perror("PTRACE_GETREGS");
std::cout << "Errno: " << errno << std::endl;
return;
}
regs.eax = __NR_exit;
regs.ebx = 222;
regs.eip = (unsigned long)inj_addr;
if(ptrace(PTRACE_SETREGS, pid, NULL, ®s) == -1)
{
perror("PTRACE_SETREGS");
std::cout << "Errno: " << errno << std::endl;
return;
}
if(ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1)
{
perror("PTRACE_DETACH");
std::cout << "Errno: " << errno << std::endl;
return;
}
std::cout << "--ptrace test ended--" << std::endl;
}
Program entry:
int main()
{
pid_t pid = get_process_id("target");
std::cout << "PID: " << pid << std::endl;
std::string lib_path = "<my_path>/ptrace-test/libtest.so";
load_library(pid, lib_path, RTLD_LAZY);
return 0;
}
Output:
PID: 2383
PTRACE_SETREGS: Input/output error
Errno: 5
If you need the whole project as a 'minimal' reproducible example, here you go: https://github.com/rdbo/ptrace-test
The PID is correct, I'm running as root, both the tracer and the tracee are compiled with G++ on 32 bits. Running up-to-date Manjaro. Any ideas?
I fixed it. Don't ask me how, though, I have no clue. I followed the exact same logic and out of sudden it worked. I used the working test_ptrace and kept putting the load_library code on it line by line to see what could be causing the problem. Turns out, I got it fixed and still don't know what it was. Anyways, here's the code (it is a bit messed up, because I didn't expect it to work):
void load_library(pid_t pid, std::string lib_path)
{
int status;
struct user_regs_struct old_regs, regs;
unsigned char inj_buf[] =
{
0x51, //push ecx
0x53, //push ebx
0xFF, 0xD0, //call eax
0xCC, //int3 (SIGTRAP)
};
size_t inj_size = sizeof(inj_buf) + lib_path.size();
void* inj_addr = allocate_memory(pid, inj_size, PROT_EXEC | PROT_READ | PROT_WRITE);
void* path_addr = (void*)((uintptr_t)inj_addr + sizeof(inj_buf));
write_memory(pid, inj_addr, inj_buf, sizeof(inj_buf));
write_memory(pid, path_addr, (void*)lib_path.c_str(), lib_path.size());
std::cout << "--ptrace test started--" << std::endl;
if(ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1)
{
perror("PTRACE_ATTACH");
std::cout << "Errno: " << errno << std::endl;
return;
}
wait(&status);
if(ptrace(PTRACE_GETREGS, pid, NULL, &old_regs) == -1)
{
perror("PTRACE_GETREGS");
std::cout << "Errno: " << errno << std::endl;
return;
}
regs = old_regs;
long dlopen_ex = 0xf7c28700;
regs.eax = dlopen_ex;
regs.ebx = (long)path_addr;
regs.ecx = RTLD_LAZY;
regs.eip = (unsigned long)inj_addr;
if(ptrace(PTRACE_SETREGS, pid, NULL, ®s) == -1)
{
perror("PTRACE_SETREGS");
std::cout << "Errno: " << errno << std::endl;
return;
}
ptrace(PTRACE_CONT, pid, NULL, NULL);
waitpid(pid, &status, WSTOPPED);
ptrace(PTRACE_SETREGS, pid, NULL, &old_regs);
if(ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1)
{
perror("PTRACE_DETACH");
std::cout << "Errno: " << errno << std::endl;
return;
}
deallocate_memory(pid, inj_addr, inj_size);
std::cout << "--ptrace test ended--" << std::endl;
}
Output:
PID: 24615
--ptrace test started--
--ptrace test ended--
Target Process:
PID: 24615
dlopen: 0xf7c28700
Waiting...
Injected!
Waiting...
Waiting...
Waiting...
Waiting...
EDIT:
I just remembered I ran the following command as root (could've been it, not sure though):
echo 0 > /proc/sys/kernel/yama/ptrace_scope
EDIT2: It was not it, the code is still working after a reboot. Also, I improved the code a bit on the GitHub repository.
I have the following code that creates a file using CreateFile with the FILE_FLAG_OVERLAPPED flag, and then calls WriteFile 100 times in a loop, passing in an OVERLAPPED structure
uint64_t GetPreciseTickCount()
{
FILETIME fileTime;
GetSystemTimePreciseAsFileTime(&fileTime);
ULARGE_INTEGER large;
large.LowPart = fileTime.dwLowDateTime;
large.HighPart = fileTime.dwHighDateTime;
return large.QuadPart;
}
uint64_t g_blockedTime = 0, g_waitTime = 0;
int main()
{
auto hFile = CreateFile(
L"test.dat",
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
std::cout << "CreateFile failed with err " << GetLastError() << std::endl;
return 1;
}
uint32_t bufferSize = 4*1024*1024;
char* buffer = (char*)_aligned_malloc(bufferSize, 4096);
const int loop = 100;
LARGE_INTEGER endPosition;
endPosition.QuadPart = bufferSize * loop;
auto sfpRet = SetFilePointerEx(hFile, endPosition, nullptr, FILE_BEGIN);
if (sfpRet == INVALID_SET_FILE_POINTER)
{
std::cout << "SetFilePointer failed with err " << GetLastError() << std::endl;
return 1;
}
if (0 == SetEndOfFile(hFile))
{
std::cout << "SetEndOfFile failed with err " << GetLastError() << std::endl;
return 1;
}
auto start = GetPreciseTickCount();
OVERLAPPED overlapped;
auto completionEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
for (int i = 0; i < loop; ++i)
{
overlapped.hEvent = completionEvent;
overlapped.Offset = i * bufferSize;
overlapped.OffsetHigh = 0;
overlapped.Internal = 0;
overlapped.InternalHigh = 0;
auto writeFileStart = GetPreciseTickCount();
auto err = WriteFile(
hFile,
buffer,
bufferSize,
nullptr,
&overlapped);
auto writeFileEnd = GetPreciseTickCount();
g_blockedTime += (writeFileEnd - writeFileStart) / 10;
if (err == FALSE)
{
auto lastErr = GetLastError();
if (lastErr != ERROR_IO_PENDING)
{
std::cout << "WriteFile failed with err " << lastErr << std::endl;
return 1;
}
auto waitErr = WaitForSingleObject(overlapped.hEvent, INFINITE);
g_waitTime += (GetPreciseTickCount() - writeFileEnd) / 10;
if (waitErr != 0)
{
std::cout << "WaitForSingleObject failed with err " << waitErr << std::endl;
return 1;
}
}
}
auto end = GetPreciseTickCount();
CloseHandle(hFile);
std::cout << "Took " << (end - start) / 10 << " micros" << std::endl;
std::cout << "Blocked time " << g_blockedTime << " micros" << std::endl;
std::cout << "Wait time " << g_waitTime << " micros" << std::endl;
}
The prints the following output
Took 1749086 micros
Blocked time 1700085 micros
Wait time 48896 micros
Why does WriteFile block? (as is evidenced by g_blockedTime being significantly higher than g_waitTime). Is there any way I can force it to be non-blocking?
Update: I updated the code to use SetFilePointerEx and SetEndOfFile before the loop. Still seeing the same blocking problem.
The solution is to call SetFilePointerEx, SetEndOfFile, and SetFileValidData before the loop. Then subsequent calls to WriteFile within the loop become non-blocking.
uint64_t GetPreciseTickCount()
{
FILETIME fileTime;
GetSystemTimePreciseAsFileTime(&fileTime);
ULARGE_INTEGER large;
large.LowPart = fileTime.dwLowDateTime;
large.HighPart = fileTime.dwHighDateTime;
return large.QuadPart;
}
uint64_t g_blockedTime = 0, g_waitTime = 0;
int main()
{
HANDLE hToken;
auto openResult = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
if (!openResult)
{
std::cout << "OpenProcessToken failed with err " << GetLastError() << std::endl;
return 1;
}
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
auto lookupResult = LookupPrivilegeValue(NULL, SE_MANAGE_VOLUME_NAME, &tp.Privileges[0].Luid);
if (!lookupResult)
{
std::cout << "LookupPrivilegeValue failed with err " << GetLastError() << std::endl;
return 1;
}
auto adjustResult = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
if (!adjustResult || GetLastError() != ERROR_SUCCESS)
{
std::cout << "AdjustTokenPrivileges failed with err " << GetLastError() << std::endl;
return 1;
}
auto hFile = CreateFile(
L"test.dat",
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
std::cout << "CreateFile failed with err " << GetLastError() << std::endl;
return 1;
}
uint32_t bufferSize = 4*1024*1024;
char* buffer = (char*)_aligned_malloc(bufferSize, 4096);
const int loop = 100;
auto start = GetPreciseTickCount();
LARGE_INTEGER endPosition;
endPosition.QuadPart = bufferSize * loop;
auto setFileErr = SetFilePointerEx(hFile, endPosition, nullptr, FILE_BEGIN);
if (setFileErr == INVALID_SET_FILE_POINTER)
{
std::cout << "SetFilePointer failed with err " << GetLastError() << std::endl;
return 1;
}
if (!SetEndOfFile(hFile))
{
std::cout << "SetEndOfFile failed with err " << GetLastError() << std::endl;
return 1;
}
if (!SetFileValidData(hFile, bufferSize * loop))
{
std::cout << "SetFileValidData failed with err " << GetLastError() << std::endl;
return 1;
}
OVERLAPPED overlapped;
auto completionEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
for (int i = 0; i < loop; ++i)
{
overlapped.hEvent = completionEvent;
overlapped.Offset = i * bufferSize;
overlapped.OffsetHigh = 0;
overlapped.Internal = 0;
overlapped.InternalHigh = 0;
auto writeFileStart = GetPreciseTickCount();
auto err = WriteFile(
hFile,
buffer,
bufferSize,
nullptr,
&overlapped);
auto writeFileEnd = GetPreciseTickCount();
g_blockedTime += (writeFileEnd - writeFileStart) / 10;
if (err == FALSE)
{
auto lastErr = GetLastError();
if (lastErr != ERROR_IO_PENDING)
{
std::cout << "WriteFile failed with err " << lastErr << std::endl;
return 1;
}
auto waitErr = WaitForSingleObject(overlapped.hEvent, INFINITE);
g_waitTime += (GetPreciseTickCount() - writeFileEnd) / 10;
if (waitErr != 0)
{
std::cout << "WaitForSingleObject failed with err " << waitErr << std::endl;
return 1;
}
}
}
auto end = GetPreciseTickCount();
CloseHandle(hFile);
std::cout << "Took " << (end - start) / 10 << " micros" << std::endl;
std::cout << "Blocked time " << g_blockedTime << " micros" << std::endl;
std::cout << "Wait time " << g_waitTime << " micros" << std::endl;
}
This produces the following output
Took 1508131 micros
Blocked time 19719 micros
Wait time 1481362 micros
Also, check out this article.
So I have been developing something for multi-computer use (I'm working on a botnet in order to prove for a school project that computers can be easily hacked as a project for GITA) and I can't seem to make a connection with the server and client. The client can connect via 127.0.0.1, however, when attempted to connect via IPv4 or the external ip (can be found www.whatsmyip.org) it doesn't seem to work. So I have tried everything, even disabling my firewall but nothing.
I'm wondering if I happened to make a mistake in my code?
Client:
#include "client.h"
Client* Client::clientptr;
int Client::Initalize(const char* add)
{
char ownPth[MAX_PATH];
// When NULL is passed to GetModuleHandle, the handle of the exe itself is returned
HMODULE hModule = GetModuleHandle(NULL);
if (hModule != NULL)
{
// Use GetModuleFileName() with module handle to get the path
GetModuleFileName(hModule, ownPth, (sizeof(ownPth)));
std::cout << ownPth << std::endl;
}
else
{
std::cout << "Module handle is NULL" << std::endl;
}
WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsaData) != 0)
{
std::cout << "ERROR: WINSOCK INVALID!" << std::endl;
exit(0);
}
std::cout << "Setting SOCKADDR_IN addr..." << std::endl;
addrlen = sizeof(addr);
addr.sin_addr.s_addr = inet_addr(add);
addr.sin_port = htons(4403);
addr.sin_family = AF_INET;
connection = socket(AF_INET, SOCK_STREAM, NULL);
while (true)
{
std::cout << "Attempting connection..." << std::endl;
if (connect(connection, (SOCKADDR*)&addr, addrlen) > 0 || connect == 0)
{
std::cout << "Connection established!" << std::endl;
break;
}
std::cout << "Error: Failed to connect! Retrying... " << std::endl;
Sleep(1000);
}
clientptr = this;
return 0;
}
int Client::Run()
{
std::cout << std::endl << "Running..." << std::endl;
while (true)
{
Sleep(10);
}
return 0;
}
Server:
#include "server.h"
Server* Server::serverptr; //Serverptr is necessary so the static ClientHandler method can access the server instance/functions.
int Server::Initalize()
{
std::cout << "Setting crash handler..." << std::endl;
std::cout << "Looking at winsock dll version..." << std::endl;
WSADATA wsaData;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsaData) != 0)
{
MessageBoxA(NULL, "Winsock startup failed", "Error", MB_OK | MB_ICONERROR);
exit(1);
}
std::cout << "Creating listening socket..." << std::endl;
addrlen = sizeof(addr);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(4403);
addr.sin_family = AF_INET;
std::cout << "The socket data addr "
<< "{"
<< "addr.sin_addr.s_addr = " << addr.sin_addr.s_addr
<< ", addr.sin_port = " << addr.sin_port
<< ", addr.sin_family = " << addr.sin_family
<< "}" << std::endl;
sListen = socket(AF_INET, SOCK_STREAM, NULL); //Create socket to listen for new connections
if (bind(sListen, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) //Bind the address to the socket, if we fail to bind the address..
{
std::string ErrorMsg = "Failed to bind the address to our listening socket. Winsock Error:" + std::to_string(WSAGetLastError());
MessageBoxA(NULL, ErrorMsg.c_str(), "Error", MB_OK | MB_ICONERROR);
exit(1);
}
if (listen(sListen, SOMAXCONN) == SOCKET_ERROR) //Places sListen socket in a state in which it is listening for an incoming connection. Note:SOMAXCONN = Socket Oustanding Max connections, if we fail to listen on listening socket...
{
std::string ErrorMsg = "Failed to listen on listening socket. Winsock Error:" + std::to_string(WSAGetLastError());
MessageBoxA(NULL, ErrorMsg.c_str(), "Error", MB_OK | MB_ICONERROR);
exit(1);
}
std::cout << "Finalizing..." << std::endl;
output = false;
currClient = 0;
std::cout << "Setting serverptr..." << std::endl;
serverptr = this;
std::cout << "Creating Threads..." << std::endl;
serverptr->Listening = false;
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Listen, NULL, NULL, NULL); //Create thread that will manage all outgoing packets
while (serverptr->Listening == false);
std::cout << "Done Initalizing!" << std::endl << std::endl;
return 0;
}
int Server::Run()
{
std::cout << "Running server...";
serverptr->Listening = true;
while (true)
{
std::string userinput;
int inputInt;
HANDLE hConsoe = GetStdHandle(STD_OUTPUT_HANDLE);
while (true)
{
std::cout << std::endl << "] ";
std::getline(std::cin, userinput);
serverptr->HandleInput(userinput);
}
}
return 0;
}
void Server::Listen()
{
if (serverptr->output)
std::cout << "Listener socket running..." << std::endl;
serverptr->Listening = true;
while (true)
{
if (serverptr->Listening == true)
{
SOCKET newConnection //the connection for the socket
= accept(serverptr->sListen, (SOCKADDR*)&serverptr->addr, &serverptr->addrlen); //Accept a new connection
if (newConnection == 0)
{
if (serverptr->output)
std::cout << "FAILED TO ACCEPT THE CLIENTS CONNECTION!" << std::endl;
}
else
{
if (serverptr->output)
{
std::cout << "A connection has been made [" << inet_ntoa(serverptr->addr.sin_addr) << "]!" << std::endl;
std::cout << "Creating Client(" << newConnection << ")..." << std::endl;
}
Client newClient(newConnection, serverptr->addr);
int connectionId = serverptr->clients.size();
serverptr->clients.push_back(newClient);
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)RecvClient, NULL, NULL, NULL); //Create thread that will manage all incomming packets
int index = serverptr->clients.size() - 1;
while (!serverptr->clients[index].Listening);
if (serverptr->output)
std::cout << "Client success [" << (index + 1) << "]!" << std::endl;
}
}
}
return;
}
void Server::RecvClient()
{
int index = serverptr->clients.size() - 1;
char data[1600];
if (serverptr->output)
std::cout << "Listening for client[" << (index + 1) << "]..." << std::endl;
serverptr->clients[index].Listening = true;
while (true)
{
recv(serverptr->clients[index]._socket, data, sizeof(data), 0);
if (serverptr->output)
std::cout << "Data Recieved from client[" << (index + 1) << "]!" << std::endl;
if ((int)data[0] < 0)
{
if (serverptr->output)
std::cout << "Client [" << (index + 1) << "] is disconnecting with the current code {" << (int)data[0] << "}..." << std::endl;
serverptr->DisconnectClient(index);
break;
}
}
if (serverptr->output)
std::cout << "No longer listening for client[" << (index + 1) << "]!" << std::endl;
}
void Server::HandleInput(std::string string)
{
std::string sHandle = string;
std::istringstream iss(string);
std::vector<std::string> sTokens((std::istream_iterator<std::string>(iss)),
std::istream_iterator<std::string>());
if (sHandle == "cls")
{
system("cls");
return;
}
if (sHandle == "list")
{
int index = serverptr->clients.size() - 1;
std::cout << "Total Clients: " << serverptr->clients.size() << std::endl;
for (int i = 0; i < serverptr->clients.size(); i++)
{
std::cout << (char)195 << (char)196 << " Client [" << i + 1 << "] {" << serverptr->clients[i]._socket << ", " << inet_ntoa(serverptr->clients[i]._address.sin_addr) << "}" << std::endl;
}
return;
}
if (sHandle == "data")
{
std::cout << "Toggling data output..." << std::endl;
serverptr->output = true;
return;
}
if (sTokens[0] == "broadcast")
{
int change = 0;
std::cout << "Toggling client: ";
if (sTokens.size() > 1)
{
std::stringstream strings(sTokens[1]);
strings >> change;
if (change > serverptr->clients.size())
{
change = serverptr->clients.size();
}
}
if (change > 0) std::cout << change << std::endl;
else std::cout << "All" << std::endl;
serverptr->currClient = change;
return;
}
std::cout << "Error: Unknown command!" << std::endl;
return;
}
void Server::DisconnectClient(int id)
{
if (serverptr->output)
std::cout << "void Server::DisconnectClient(" << id << ")..." << std::endl;
closesocket(serverptr->clients[id]._socket);
serverptr->clients.erase(serverptr->clients.begin() + (id));
return;
}
Client::Client(SOCKET socket, SOCKADDR_IN address)
{
this->_address = address;
this->_socket = socket;
this->Listening = false;
}
I get an example of c++ code from msdn, where I try to get info about my partitions, but in this code my DeviceIoControl methom returns 0, end error code 3. How can I fix this error?
Code here:
#define WINVER 0x0500
#include <windows.h>
#include <winioctl.h>
#include <iostream>
#include <stdio.h>
void DisplayVolumeInfo(CHAR *volume)
{
HANDLE hDevice = CreateFileA(
volume,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_SYSTEM,
NULL);
if (hDevice != INVALID_HANDLE_VALUE)
{
PARTITION_INFORMATION partInfo;
DWORD retcount = 0;
BOOL res = DeviceIoControl(
hDevice,
IOCTL_DISK_GET_PARTITION_INFO,
(LPVOID)NULL,
(DWORD)0,
(LPVOID)&partInfo,
sizeof(partInfo),
&retcount,
(LPOVERLAPPED)NULL);
if (res)
std::cout << "Volume size = " << partInfo.PartitionLength.QuadPart << " bytes (" << (unsigned long long)(partInfo.PartitionLength.QuadPart / 1024 / 1024) << "Mb)" << std::endl;
else
std::cout << "Can't do IOCTL_DISK_GET_PARTITION_INFO (error code=" << GetLastError() << ")" << std::endl;
DISK_GEOMETRY diskGeometry;
retcount = 0;
res = DeviceIoControl(
hDevice,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL, 0,
&diskGeometry, sizeof(diskGeometry),
&retcount,
(LPOVERLAPPED)NULL);
if (res)
{
std::cout << "Cylinders = " << diskGeometry.Cylinders.QuadPart << std::endl;
std::cout << "Tracks/cylinder = " << diskGeometry.TracksPerCylinder << std::endl;
std::cout << "Sectors/track = " << diskGeometry.SectorsPerTrack << std::endl;
std::cout << "Bytes/sector = " << diskGeometry.BytesPerSector << std::endl;
}
else
std::cout << "Can't do IOCTL_DISK_GET_DRIVE_GEOMETRY (error code=" << GetLastError() << ")" << std::endl;
CloseHandle(hDevice);
}
else
std::cout << "Error opening volume " << volume << " (error code=" << GetLastError() << ")" << std::endl;
}
int main()
{
DWORD CharCount = 0;
char DeviceName[MAX_PATH] = "";
DWORD Error = ERROR_SUCCESS;
HANDLE FindHandle = INVALID_HANDLE_VALUE;
BOOL Found = FALSE;
size_t Index = 0;
BOOL Success = FALSE;
char VolumeName[MAX_PATH] = "";
//
// Enumerate all volumes in the system.
FindHandle = FindFirstVolumeA(VolumeName, MAX_PATH);
if (FindHandle == INVALID_HANDLE_VALUE)
{
Error = GetLastError();
printf("FindFirstVolume failed with error code %d\n", Error);
return 0;
}
for (;;)
{
//
// Skip the \\?\ prefix and remove the trailing backslash.
Index = strlen(VolumeName) - 1;
if (VolumeName[0] != '\\' ||
VolumeName[1] != '\\' ||
VolumeName[2] != '?' ||
VolumeName[3] != '\\' ||
VolumeName[Index] != '\\')
{
Error = ERROR_BAD_PATHNAME;
printf("FindFirstVolume/FindNextVolume returned a bad path: %s\n", VolumeName);
break;
}
//
// QueryDosDeviceW does not allow a trailing backslash,
// so temporarily remove it.
VolumeName[Index] = '\0';
CharCount = QueryDosDeviceA(&VolumeName[4], DeviceName, MAX_PATH);
VolumeName[Index] = '\\';
if ( CharCount == 0 )
{
Error = GetLastError();
printf("QueryDosDevice failed with error code %d\n", Error);
break;
}
printf("\nFound a device:\n %s", DeviceName);
printf("\nVolume name: %s", VolumeName);
printf("\n");
DisplayVolumeInfo(VolumeName);
//
// Move on to the next volume.
Success = FindNextVolumeA(FindHandle, VolumeName, MAX_PATH);
if ( !Success )
{
Error = GetLastError();
if (Error != ERROR_NO_MORE_FILES)
{
printf("FindNextVolumeW failed with error code %d\n", Error);
break;
}
//
// Finished iterating
// through all the volumes.
Error = ERROR_SUCCESS;
break;
}
}
FindVolumeClose(FindHandle);
FindHandle = INVALID_HANDLE_VALUE;
return 0;
}
Has anybody met this problem?
P.S. I work on Windows 7 x32