WinSock2 Error 10093 on recv - windows

So I'm building a multithreaded socket library in windows and I'm getting the WSA Not Started error when I call recv, even though I successfully get a client to connect to the server. I also had it working before I threaded it, but I don't know what happened since then. Any help would be appreciated.
Spocket.hpp
#include <iostream>
#include <string>
#include <Windows.h>
#pragma comment (lib,"ws2_32.lib")
static bool initialized_ = false;
class Spocket
{
protected:
WSADATA wsaData_;
SOCKET hSocket_;
sockaddr_in service_;
std::string addr_;
USHORT port_;
int exitCode_;
public:
Spocket() {
initialize();
create_socket();
}
Spocket(std::string addr, USHORT port)
: addr_( addr ), port_( port ) {
initialize();
create_socket();
}
Spocket(Spocket spock, SOCKET sock)
: hSocket_( sock ),
wsaData_( spock.wsaData_ ),
service_( spock.service_ ),
addr_( spock.addr_ ),
port_( spock.port_ )
{
initialize();
}
virtual ~Spocket() { close(); }
void initialize();
void create_socket();
void close();
template<typename T>
int recv_data(T* i) {
int ret = recv( hSocket_, reinterpret_cast<char*>(i), 32, 0 );
if( ret == SOCKET_ERROR )
cerr << WSAGetLastError() << endl;
return ret;
}
template<typename T>
int send_data(T* i) {
int ret = send( hSocket_, reinterpret_cast<char*>(i), sizeof(i), 0 );
if( ret == SOCKET_ERROR )
cerr << WSAGetLastError() << endl;
return ret;
}
};
class ServerSpocket : public Spocket
{
public:
ServerSpocket(std::string addr, USHORT port);
Spocket* accept_clients();
};
class ClientSpocket : public Spocket
{
public:
ClientSpocket(std::string addr, USHORT port);
};
Spocket.cpp
#include <iostream>
using namespace std;
#include "../include/spocket.hpp"
void Spocket::initialize() {
if(!initialized_)
{
cout << "Initializing socket..." << endl;
exitCode_ = EXIT_SUCCESS;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData_ );
if( iResult != NO_ERROR ) {
cerr << "WSAStartup failed" << endl;
exitCode_ = EXIT_FAILURE;
close();
}
initialized_ = true;
}
}
void Spocket::create_socket() {
hSocket_ = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if( hSocket_ == INVALID_SOCKET )
{
cerr << "Error at socket(): " << WSAGetLastError() << endl;
exitCode_ = EXIT_FAILURE;
close();
}
service_.sin_family = AF_INET;
service_.sin_addr.s_addr = inet_addr(addr_.c_str());
service_.sin_port = htons(port_);
}
void Spocket::close() {
closesocket( hSocket_ );
WSACleanup();
}
ServerSpocket::ServerSpocket(std::string addr, USHORT port) : Spocket(addr, port) {
if( bind( hSocket_, (SOCKADDR*)&service_, sizeof(service_) ) == SOCKET_ERROR )
{
cerr << "Failed to bind" << endl;
exitCode_ = EXIT_FAILURE;
close();
}
if( listen( hSocket_, 1 ) == SOCKET_ERROR )
{
cerr << "Error listening on socket" << endl;
exitCode_ = EXIT_FAILURE;
close();
}
}
Spocket* ServerSpocket::accept_clients() {
cout << "Waiting for connection...\n";
SOCKET hAccepted = INVALID_SOCKET;
while( hAccepted == INVALID_SOCKET )
hAccepted = accept( hSocket_, NULL, NULL );
return new Spocket( *this, hAccepted );
}
ClientSpocket::ClientSpocket(std::string addr, USHORT port) : Spocket(addr, port) {
if( connect( hSocket_, (SOCKADDR*)&service_, sizeof(service_) ) == SOCKET_ERROR )
{
cerr << "Failed to connect" << endl;
exitCode_ = EXIT_FAILURE;
close();
}
}
Server_main.cpp
#include <iostream>
#include <fstream>
#include <vector>
#include <spocket.hpp>
using namespace std;
vector<HANDLE> hThreads;
vector<DWORD> dwThreadIds;
struct ConnectionInfo
{
string ip;
unsigned int port;
ConnectionInfo( string ip_, unsigned int port_ ) : ip(ip_), port(port_){}
};
static ConnectionInfo ci( "127.0.0.1", 27015 );
DWORD WINAPI clientSession( LPVOID lpParam )
{
// create new socket to listen for connection attempts
ConnectionInfo arg = *reinterpret_cast<ConnectionInfo*>(lpParam);
ServerSpocket listenSock( arg.ip, arg.port );
// spawn a duplicate thread when a connection is made, and close the current listening socket
Spocket* sessionSock = listenSock.accept_clients();
listenSock.close();
cout << "client connected..." << endl;
/*
hThreads.push_back( CreateThread( NULL, 0, clientSession, &ci, 0, NULL ) );
*/
// service the connected client
string msg;
while( sessionSock->recv_data(&msg) != SOCKET_ERROR && msg != "goodbye!" )
{
cout << msg << endl;
msg.clear();
}
cout << "finished with client..." << endl;
// wait quietly for server shutdown
while( true )
Sleep( 200 );
return 0;
}
int main() {
cout << "[Server]" << endl;
cout << "starting up..." << endl;
hThreads.push_back( CreateThread( NULL, 0, clientSession, &ci, 0, NULL ) );
string input = "";
do
cin >> input;
while( input != "exit" );
// close all thread handles here
cout << "shutting down..." << endl;
return 0;
}

I beleive you must keep the "original" socket alive. Move listenSock.close(); after the sessionSock->recv_data() loop.

Related

Why does ReadProcessMemory fail so often with ERROR_PARTIAL_COPY?

The following program tries to scan read/write pages of a foreign application with ReadProcessMemory():
#include <Windows.h>
#include <iostream>
#include <vector>
#include <charconv>
#include <cstring>
#include <vector>
#include <stdexcept>
#include <sstream>
#include <cctype>
#include <fstream>
#include <cmath>
using namespace std;
vector<vector<MEMORY_BASIC_INFORMATION>> pageTree( HANDLE hProcess, DWORD dwMask );
using XHANDLE = unique_ptr<void, decltype([]( HANDLE h ) { h && h != INVALID_HANDLE_VALUE && CloseHandle( h ); })>;
int main( int argc, char **argv )
{
if( argc < 2 )
return EXIT_FAILURE;
try
{
DWORD dwProcessId = [&]() -> DWORD
{
DWORD dwRet;
if( from_chars_result fcr = from_chars( argv[1], argv[1] + strlen( argv[1] ), dwRet ); fcr.ec != errc() || *fcr.ptr )
throw invalid_argument( "process-id unparseable" );
return dwRet;
}();
XHANDLE hProcess( [&]() -> HANDLE
{
HANDLE hRet = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId );
if( !hRet )
throw system_error( (int)GetLastError(), system_category(), "can't open process" );
return hRet;
}() );
vector<vector<MEMORY_BASIC_INFORMATION>> vvmbi = pageTree( hProcess.get(), PAGE_READWRITE );
vector<char> processRegion;
size_t
succs = 0, partialErrs = 0, errs = 0,
total = 0, read = 0, skipped = 0;
for( vector<MEMORY_BASIC_INFORMATION> const &vmbi : vvmbi )
for( MEMORY_BASIC_INFORMATION const &vmbi : vmbi )
{
processRegion.resize( vmbi.RegionSize );
size_t actuallyRead;
bool succ = ReadProcessMemory( hProcess.get(), vmbi.BaseAddress, to_address( processRegion.begin() ), vmbi.RegionSize, &actuallyRead );
succs += succ;
partialErrs += !succ && GetLastError() == ERROR_PARTIAL_COPY;
errs += !succ;
bool bytesCopied = succ || GetLastError() == ERROR_PARTIAL_COPY;
actuallyRead = bytesCopied ? actuallyRead : 0;
total += processRegion.size(),
read += actuallyRead;
skipped += bytesCopied ? processRegion.size() - actuallyRead : processRegion.size();
}
cout << "successes: " << succs << endl;
cout << "partial errs: " << partialErrs << endl;
cout << "errs: " << errs << endl;
cout << "read: " << read << endl;
cout << "skipped: " << skipped;
auto pct = []( double a, double b ) -> double { return trunc( a / b * 1000.0 + 0.5 ) / 10.0; };
cout << " (" << pct( (double)(ptrdiff_t)skipped, (double)(ptrdiff_t)total ) << "%)" << endl;
}
catch( exception const &exc )
{
cout << exc.what() << endl;
}
}
template<typename Fn>
requires requires( Fn fn, MEMORY_BASIC_INFORMATION &mbi ) { { fn( mbi ) } -> std::convertible_to<bool>; }
void enumProcessMemory( HANDLE hProcess, Fn fn );
vector<vector<MEMORY_BASIC_INFORMATION>> pageTree( HANDLE hProcess, DWORD dwMask )
{
vector<vector<MEMORY_BASIC_INFORMATION>> vvmbis;
enumProcessMemory( hProcess, [&]( MEMORY_BASIC_INFORMATION &mbi ) -> bool
{
if( !(mbi.AllocationProtect & dwMask) )
return true;
if( !vvmbis.size() || vvmbis.back().back().BaseAddress != mbi.BaseAddress )
vvmbis.emplace_back( vector<MEMORY_BASIC_INFORMATION>() );
vvmbis.back().emplace_back( mbi );
return true;
} );
return vvmbis;
}
template<typename Fn>
requires requires( Fn fn, MEMORY_BASIC_INFORMATION &mbi ) { { fn( mbi ) } -> std::convertible_to<bool>; }
void enumProcessMemory( HANDLE hProcess, Fn fn )
{
MEMORY_BASIC_INFORMATION mbi;
for( char *last = nullptr; ; last = (char *)mbi.BaseAddress + mbi.RegionSize )
{
size_t nBytes = VirtualQueryEx( hProcess, last, &mbi, sizeof mbi );
if( nBytes != sizeof mbi )
if( DWORD dwErr = GetLastError(); dwErr == ERROR_INVALID_PARAMETER )
break;
else
throw system_error( (int)dwErr, system_category(), "can't query process pages" );
if( !fn( mbi ) )
break;
}
}
This is the result from scanning explorer.exe:
successes: 316
partial errs: 282
errs: 282
read: 139862016
skipped: 4452511744 (97%)
I.e. 316 copies from the foreign address space are successful, 282 are errors with partial reads, the same number are errors at all (i.e. all errors are partial reads), and the given number of bytes are read and skipped. The total memory that has skipped is 97%.
Why does ReadProcessMemory() fail so often, or what am I doing wrong here?
Remy was mostly right. Here's the corrected code with a filter-callback on pageTree instead of a protection mask.
#include <Windows.h>
#include <iostream>
#include <vector>
#include <charconv>
#include <cstring>
#include <vector>
#include <stdexcept>
#include <sstream>
#include <cctype>
#include <fstream>
#include <cmath>
using namespace std;
template<typename FilterFn>
requires requires( FilterFn fn, MEMORY_BASIC_INFORMATION &mbi ) { { fn( mbi ) } -> std::convertible_to<bool>; }
vector<vector<MEMORY_BASIC_INFORMATION>> pageTree( HANDLE hProcess, FilterFn filterFn );
using XHANDLE = unique_ptr<void, decltype([]( HANDLE h ) { h && h != INVALID_HANDLE_VALUE && CloseHandle( h ); })>;
int main( int argc, char **argv )
{
if( argc < 2 )
return EXIT_FAILURE;
try
{
DWORD dwProcessId = [&]() -> DWORD
{
DWORD dwRet;
if( from_chars_result fcr = from_chars( argv[1], argv[1] + strlen( argv[1] ), dwRet ); fcr.ec != errc() || *fcr.ptr )
throw invalid_argument( "process-id unparseable" );
return dwRet;
}();
XHANDLE hProcess( [&]() -> HANDLE
{
HANDLE hRet = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId );
if( !hRet )
throw system_error( (int)GetLastError(), system_category(), "can't open process" );
return hRet;
}() );
vector<vector<MEMORY_BASIC_INFORMATION>> vvmbi = pageTree( hProcess.get(),
[]( MEMORY_BASIC_INFORMATION &mbi ) -> bool
{
return mbi.State == MEM_COMMIT;
} );
vector<char> processRegion;
size_t
succs = 0, partialErrs = 0, errs = 0,
total = 0, read = 0, skipped = 0;
for( vector<MEMORY_BASIC_INFORMATION> const &vmbi : vvmbi )
for( MEMORY_BASIC_INFORMATION const &vmbi : vmbi )
{
processRegion.resize( vmbi.RegionSize );
size_t actuallyRead;
bool succ = ReadProcessMemory( hProcess.get(), vmbi.BaseAddress, to_address( processRegion.begin() ), vmbi.RegionSize, &actuallyRead );
succs += succ;
partialErrs += !succ && GetLastError() == ERROR_PARTIAL_COPY;
errs += !succ;
bool bytesCopied = succ || GetLastError() == ERROR_PARTIAL_COPY;
actuallyRead = bytesCopied ? actuallyRead : 0;
total += processRegion.size(),
read += actuallyRead;
skipped += bytesCopied ? processRegion.size() - actuallyRead : processRegion.size();
}
cout << "successes: " << succs << endl;
cout << "partial errs: " << partialErrs << endl;
cout << "errs: " << errs << endl;
cout << "read: " << read << endl;
cout << "skipped: " << skipped;
auto pct = []( double a, double b ) -> double { return trunc( a / b * 1000.0 + 0.5 ) / 10.0; };
cout << " (" << pct( (double)(ptrdiff_t)skipped, (double)(ptrdiff_t)total ) << "%)" << endl;
}
catch( exception const &exc )
{
cout << exc.what() << endl;
}
}
template<typename Fn>
requires requires( Fn fn, MEMORY_BASIC_INFORMATION &mbi ) { { fn( mbi ) } -> std::convertible_to<bool>; }
void enumProcessMemory( HANDLE hProcess, Fn fn );
template<typename FilterFn>
requires requires( FilterFn fn, MEMORY_BASIC_INFORMATION &mbi ) { { fn( mbi ) } -> std::convertible_to<bool>; }
vector<vector<MEMORY_BASIC_INFORMATION>> pageTree( HANDLE hProcess, FilterFn filterFn )
{
vector<vector<MEMORY_BASIC_INFORMATION>> vvmbis;
enumProcessMemory( hProcess, [&]( MEMORY_BASIC_INFORMATION &mbi ) -> bool
{
if( !filterFn( mbi ) )
return true;
if( !vvmbis.size() || vvmbis.back().back().BaseAddress != mbi.BaseAddress )
vvmbis.emplace_back( vector<MEMORY_BASIC_INFORMATION>() );
vvmbis.back().emplace_back( mbi );
return true;
} );
return vvmbis;
}
template<typename Fn>
requires requires( Fn fn, MEMORY_BASIC_INFORMATION &mbi ) { { fn( mbi ) } -> std::convertible_to<bool>; }
void enumProcessMemory( HANDLE hProcess, Fn fn )
{
MEMORY_BASIC_INFORMATION mbi;
for( char *last = nullptr; ; last = (char *)mbi.BaseAddress + mbi.RegionSize )
{
size_t nBytes = VirtualQueryEx( hProcess, last, &mbi, sizeof mbi );
if( nBytes != sizeof mbi )
if( DWORD dwErr = GetLastError(); dwErr == ERROR_INVALID_PARAMETER )
break;
else
throw system_error( (int)dwErr, system_category(), "can't query process pages" );
if( !fn( mbi ) )
break;
}
}
Unfortunately I still get about 6% skipped memory:
successes: 2159
partial errs: 225
errs: 225
read: 706748416
skipped: 42897408 (5.7%)
Why is that ?

VirtualQueryEx() returns mostly useless data

I've written a little program to query the page-map of a process:
#include <Windows.h>
#include <iostream>
#include <vector>
#include <charconv>
#include <cstring>
#include <stdexcept>
using namespace std;
int main( int argc, char **argv )
{
if( argc < 2 )
return EXIT_FAILURE;
try
{
DWORD dwProcessId = [&]() -> DWORD
{
DWORD dwRet;
from_chars_result fcr = from_chars( argv[1], argv[1] + strlen( argv[1] ), dwRet );
if( fcr.ec != errc() || *fcr.ptr )
throw invalid_argument( "process-id unparseable" );
return dwRet;
}();
HANDLE hProcess = [&]() -> HANDLE
{
HANDLE hRet = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, dwProcessId );
if( !hRet )
throw system_error( (int)GetLastError(), system_category(), "can't open process" );
return hRet;
}();
size_t pageSize = []() -> size_t
{
SYSTEM_INFO si;
GetSystemInfo( &si );
return si.dwPageSize;
}();
using mbi_t = MEMORY_BASIC_INFORMATION;
vector<mbi_t> mbis( 0x100 );
size_t nRegions;
while( !(nRegions = VirtualQueryEx( hProcess, nullptr, to_address( mbis.begin() ), mbis.size() * sizeof(mbi_t) )) )
if( GetLastError() == ERROR_BAD_LENGTH )
mbis.resize( mbis.size() * 2 );
else
throw system_error( (int)GetLastError(), system_category(), "can't query process pages" );
mbis.resize( nRegions );
for( mbi_t const &mbi : mbis )
{
cout << "base address: " << hex << mbi.BaseAddress << endl;
cout << "allocation base: " << hex << mbi.AllocationBase << endl;
cout << dec << mbi.RegionSize / pageSize << " pages" << endl;
static struct
{
DWORD dwProtect;
char const *str;
} const protectMaps[] =
{
{ PAGE_EXECUTE, "PAGE_EXECUTE" },
{ PAGE_EXECUTE_READ, "PAGE_EXECUTE_READ" },
{ PAGE_EXECUTE_READWRITE, "PAGE_EXECUTE_READWRITE" },
{ PAGE_EXECUTE_WRITECOPY, "PAGE_EXECUTE_WRITECOPY" },
{ PAGE_NOACCESS, "PAGE_NOACCESS" },
{ PAGE_READONLY, "PAGE_READONLY" },
{ PAGE_READWRITE, "PAGE_READWRITE" },
{ PAGE_WRITECOPY, "PAGE_WRITECOPY" }
};
for( auto const &pm : protectMaps )
if( pm.dwProtect == mbi.AllocationProtect )
{
cout << "state: " << pm.str << endl;
break;
}
if( mbi.Type == MEM_IMAGE )
cout << "image";
else if( mbi.Type == MEM_MAPPED )
cout << "mapped";
else if( mbi.Type == MEM_PRIVATE )
cout << "private";
cout << endl << endl;
}
}
catch( exception const &exc )
{
cout << exc.what() << endl;
}
}
Unfortunately the program returns mostly null-data except from the number of pages with the first entry, which is the number of logical pages of the process minus 32.
What am I doing wrong here ?
The process I tried to query runs under the same token, so there coudln't be any privilege issues.
Thank you Hans ! You were right. I thoughth VirtualQueryEx() fills just a number of MEMORY_BASIC_INFORMATION. If you don't see something obvious you say in Germany that you've got tomatoes on your eyes, and yes, I had tomatoes on my eyes (not because of my style ;-)).
Here's the working code:
#include <Windows.h>
#include <iostream>
#include <vector>
#include <charconv>
#include <cstring>
#include <vector>
#include <stdexcept>
using namespace std;
vector<vector<MEMORY_BASIC_INFORMATION>> pageTree( HANDLE hProcess );
int main( int argc, char **argv )
{
if( argc < 2 )
return EXIT_FAILURE;
try
{
DWORD dwProcessId = [&]() -> DWORD
{
DWORD dwRet;
from_chars_result fcr = from_chars( argv[1], argv[1] + strlen( argv[1] ), dwRet );
if( fcr.ec != errc() || *fcr.ptr )
throw invalid_argument( "process-id unparseable" );
return dwRet;
}();
HANDLE hProcess = [&]() -> HANDLE
{
HANDLE hRet = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, dwProcessId );
if( !hRet )
throw system_error( (int)GetLastError(), system_category(), "can't open process" );
return hRet;
}();
size_t pageSize = []() -> size_t
{
SYSTEM_INFO si;
GetSystemInfo( &si );
return si.dwPageSize;
}();
vector<vector<MEMORY_BASIC_INFORMATION>> vvmbi = pageTree( hProcess );
for( vector<MEMORY_BASIC_INFORMATION> const &vmbi : vvmbi )
{
cout << "allocation base: " << hex << vmbi.front().AllocationBase << endl;
for( MEMORY_BASIC_INFORMATION const &mbi : vmbi )
{
cout << "\tbase address: " << hex << mbi.BaseAddress << endl;
cout << "\t" << dec << mbi.RegionSize / pageSize << " pages" << endl;
static struct
{
DWORD dwProtect;
char const *str;
} const protectMaps[] =
{
{ PAGE_EXECUTE, "PAGE_EXECUTE" },
{ PAGE_EXECUTE_READ, "PAGE_EXECUTE_READ" },
{ PAGE_EXECUTE_READWRITE, "PAGE_EXECUTE_READWRITE" },
{ PAGE_EXECUTE_WRITECOPY, "PAGE_EXECUTE_WRITECOPY" },
{ PAGE_NOACCESS, "PAGE_NOACCESS" },
{ PAGE_READONLY, "PAGE_READONLY" },
{ PAGE_READWRITE, "PAGE_READWRITE" },
{ PAGE_WRITECOPY, "PAGE_WRITECOPY" }
};
for( auto const &pm : protectMaps )
if( pm.dwProtect == mbi.AllocationProtect )
{
cout << "\tstate: " << pm.str << endl;
break;
}
if( mbi.Type == MEM_IMAGE )
cout << "\timage" << endl;
else if( mbi.Type == MEM_MAPPED )
cout << "\tmapped" << endl;
else if( mbi.Type == MEM_PRIVATE )
cout << "\tprivate" << endl;
cout << endl;
}
}
}
catch( exception const &exc )
{
cout << exc.what() << endl;
}
}
template<typename Fn>
requires requires( Fn fn, MEMORY_BASIC_INFORMATION &mbi ) { { fn( mbi ) } -> std::convertible_to<bool>; }
void enumProcessMemory( HANDLE hProcess, Fn fn );
vector<vector<MEMORY_BASIC_INFORMATION>> pageTree( HANDLE hProcess )
{
vector<vector<MEMORY_BASIC_INFORMATION>> vvmbis;
enumProcessMemory( hProcess, [&]( MEMORY_BASIC_INFORMATION &mbi ) -> bool
{
if( !vvmbis.size() || vvmbis.back().back().BaseAddress != mbi.BaseAddress )
vvmbis.emplace_back( vector<MEMORY_BASIC_INFORMATION>() );
vvmbis.back().emplace_back( mbi );
return true;
} );
return vvmbis;
}
template<typename Fn>
requires requires( Fn fn, MEMORY_BASIC_INFORMATION &mbi ) { { fn( mbi ) } -> std::convertible_to<bool>; }
void enumProcessMemory( HANDLE hProcess, Fn fn )
{
MEMORY_BASIC_INFORMATION mbi;
for( char *last = nullptr; ; last = (char *)mbi.BaseAddress + mbi.RegionSize )
{
size_t nBytes = VirtualQueryEx( hProcess, last, &mbi, sizeof mbi );
if( nBytes != sizeof mbi )
if( DWORD dwErr = GetLastError(); dwErr == ERROR_INVALID_PARAMETER )
break;
else
throw system_error( (int)dwErr, system_category(), "can't query process pages" );
if( !fn( mbi ) )
break;
}
}
The code now groups the allocation bases. Its segemented that parts can be extended without changing the framework.

Windows sockets. FD_ISSET always returns 0

I try to write Windows server app that accepts requests. I wan to use select() function to receive new connections and requests -- to monitor listen socket and previously established connections.
The problem is that FD_ISSET always returns 0. Here's the code. Can you please point me the mistake?
WORD wVersionRequested;
WSADATA wsaData;
int iResult;
// Initializing WSA
wVersionRequested = MAKEWORD( 2, 2 );
iResult = WSAStartup( wVersionRequested, &wsaData );
if ( iResult != 0 )
{
std::cout << "WSAStartup failed with error: " << WSAGetLastError() << std::endl;
return false;
}
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
{
WSACleanup();
std::cout << "Could not find a usable version of Winsock.dll" << std::endl;
return false;
}
int iResult;
struct addrinfo *result = NULL;
struct addrinfo hints;
std::stringstream ss;
ss << DEFAULT_PORT;
memset( &hints, 0, sizeof( hints ) );
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo( NULL, ss.str().c_str(), &hints, &result );
if ( iResult != 0 )
{
std::cout << "getaddrinfo() failed with error: " << WSAGetLastError() << std::endl;
return false;
}
// Create a SOCKET for connecting to server
m_listenSocket = socket( result->ai_family, result->ai_socktype, result->ai_protocol );
if ( m_listenSocket == INVALID_SOCKET )
{
std::cout << "socket() failed with error: " << WSAGetLastError() << std::endl;
return false;
}
// Setup the TCP listening socket
iResult = bind( m_listenSocket, result->ai_addr, ( int ) result->ai_addrlen );
if ( iResult == SOCKET_ERROR )
{
std::cout << "bind() failed with error: " << WSAGetLastError() << std::endl;
freeaddrinfo( result );
return false;
}
freeaddrinfo( result );
// Listen for the TCP listening socket
if ( listen( m_listenSocket, SOMAXCONN ) == SOCKET_ERROR )
{
std::cout << "listen() failed with error: " << WSAGetLastError() << std::endl;
return false;
}
fd_set active_fd_set;
fd_set read_fd_set;
// Initialize the set of active sockets.
FD_ZERO( &active_fd_set );
FD_SET( m_listenSocket, &active_fd_set );
while ( !m_forceStopMessages )
{
read_fd_set = active_fd_set;
int retVal = select( FD_SETSIZE, &read_fd_set, NULL, NULL, NULL );
if ( retVal < 0 )
{
std::cout << "select() failed with error: " << WSAGetLastError() << std::endl;
}
int readySockets = ( FD_SETSIZE < retVal ) ? FD_SETSIZE : retVal;
// Service all the sockets with input pending.
for ( int i = 0; i < readySockets; ++i )
{
if ( FD_ISSET( i, &read_fd_set ) )
{
if ( i == m_listenSocket )
{
// Accept a client socket
FD_SET( clientSocket, &active_fd_set );
}
else
{
/* Data arriving on an already-connected socket. */
FD_CLR( i, &active_fd_set );
}
}
}
}
FD_ISSET takes a socket handle as the first parameter, not an index.

error C1083 visual studio 2013 for winsock server

i'm new at this website.
i searched a lot for a solution but i didn't find nothing about it.
i programmed a server and a client on another project and it was working but i wanted to re-program it to have a better results.
but i dunno why i have some errors: error C1083: impossible to open: 'Debug\chatserver.pch': No such file or directory c:\users\x\documents\visual studio 2013\projects\chatserver\chatserver\chatserver.cpp
before this error, i had another error on 'itoa' function: C4996 'itoa' POSIX ...
(itoa function was working on my 1st server project)
also i had error on LNK 2011 to .obj
this is the code:
#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <cstdlib>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_PORT "27015"
using namespace std;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket;
SOCKET* Connessioni;
int nConn = 0;
struct Buffer
{
int ID;
char nickname[20];
char messaggio[1024];
};
int ServerThread(int ID)
{
Buffer buff;
char* Recv = new char[1024];
char* Pnick = new char[20];
char* Send = new char[1024];
Recv = NULL;
Pnick = NULL;
Send = NULL;
for (;;){
if (recv(Connessioni[ID], Recv, 1024, NULL) && recv(Connessioni[ID], Pnick, 20, NULL))
buff.ID = ID;
memcpy(buff.nickname, Pnick, 1024);
memcpy(buff.messaggio, Recv, 1024);
memcpy(Send, &buff, sizeof(Buffer));
for (int i = 0; i != nConn; i++)
{
if (Connessioni[i] == Connessioni[ID])
{
}
else{
send(Connessioni[i], Send, sizeof(Buffer), NULL);
}
}
delete Recv;
delete Send;
delete Pnick;
delete &Recv;
delete &Send;
delete &Pnick;
}
return 0;
}
int InitWinSock()
{
int RetVal = 0;
WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 2);
RetVal = WSAStartup(DllVersion, &wsaData);
if (RetVal != 0)
MessageBoxA(NULL, "WSA error, please retry", "Error", MB_OK | MB_ICONERROR);
return RetVal;
}
int main()
{
struct addrinfo *result = NULL, *ptr = NULL, hints;
ZeroMemory(&hints, sizeof (hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
int controllo_struct = getaddrinfo(NULL,DEFAULT_PORT, &hints, &result);
if (controllo_struct != 0)
{
MessageBoxA(NULL, "getinfo failes \n", "Error", MB_OK | MB_ICONERROR);
WSACleanup();
return 1;
}
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET)
{
MessageBoxA(NULL, "Error at Socket, please retry \n", "Error", MB_OK | MB_ICONERROR);
freeaddrinfo(result);
WSACleanup();
}
int controllo_bind = bind(ListenSocket,result->ai_addr,(int)result->ai_addrlen);
if (controllo_bind == SOCKET_ERROR)
{
MessageBoxA(NULL, "bind ha fallito \n", "Error", MB_OK | MB_ICONERROR);
cout << WSAGetLastError() << endl;
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR){
MessageBoxA(NULL, "Listen ha fallito \n", "Error", MB_OK | MB_ICONERROR);
cout << WSAGetLastError() << endl;
closesocket(ListenSocket);
return 1;
}
ClientSocket = INVALID_SOCKET;
int addrlen = sizeof(hints);
for (;;){
if (ClientSocket = accept(ListenSocket, (SOCKADDR*)&hints, &addrlen))
Connessioni = (SOCKET*)calloc(SOMAXCONN, sizeof(hints));
cout << "connessione accettata " << endl;
Connessioni[nConn] = ClientSocket;
char* nickname = new char[20];
ZeroMemory(nickname, sizeof(nickname));
//itoa(nConn,nickname,10);
//nickname = (char*)nConn;
send(Connessioni[nConn], nickname, sizeof(nickname), NULL);
++nConn;
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ServerThread, (LPVOID)(nConn - 1), NULL, NULL);
delete nickname;
}
return 0;
}
RESOLVED:
DISABLED: "PRECOMPILED HEADER"
on c/c++ -> all options ->> "precompiled header (selected: NO)

pem file from Microsoft serialized store (SST) files

I have SST files form Microsoft which I need to add to a java truststore.
The problem is all tools that Microsoft provides, add the certs from SST files to windows stores, so difficult to get PEM files form the SST files. If I run certmgr.exe (not certmgr.msc), I can get public key and all that but no cert (in pem or der), I saw bunch of VB scripts and powershell to load them using SST file into System.Security.Cryptography.X509Certificates.X509Certificate2Collection object, but still can't find a way to output as PEM (or der ) formated certificates.
Any suggestions?
S
You could use CAPI to open the SST file as a certificate store then enumerate over the certificates in the file. The following code does this and outputs the certificates in DER form to a file using a SHA1 hash of the certificate as a filename. The first argument is the output folder. The remaining one or more arguments are your SST files.
#include <stdio.h>
#include <tchar.h>
#include "windows.h"
#include "wincrypt.h"
#include "atlbase.h"
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
std::string GetHexRepresentation(const unsigned char * Bytes, size_t Length)
{
std::ostringstream os;
os.fill('0');
os<<std::hex;
for(const unsigned char * ptr=Bytes;ptr<Bytes+Length;ptr++)
os<<std::setw(2)<<(unsigned int)*ptr;
std::string retval = os.str();
std::transform(retval.begin(), retval.end(),retval.begin(), ::toupper);
return retval;
}
BOOL WriteToFileWithHashAsFilename(PCCERT_CONTEXT pPrevCertContext, TCHAR* outputDir)
{
#undef RETURN
#define RETURN(rv) \
{ \
if( hHash ) CryptDestroyHash(hHash); \
if( hProv ) CryptReleaseContext(hProv, 0); \
return rv; \
}
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
BYTE byteFinalHash[20];
DWORD dwFinalHashSize = 20;
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
std::cout << "CryptAcquireContext failed: " << GetLastError() << std::endl;
RETURN(FALSE);
}
if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
{
std::cout << "CryptCreateHash failed: " << GetLastError() << std::endl;
RETURN(FALSE);
}
if (!CryptHashData(hHash, pPrevCertContext->pbCertEncoded, pPrevCertContext->cbCertEncoded, 0))
{
std::cout << "CryptHashData failed: " << GetLastError() << std::endl;
RETURN(FALSE);
}
if (!CryptGetHashParam(hHash, HP_HASHVAL, byteFinalHash, &dwFinalHashSize, 0))
{
std::cout << "CryptGetHashParam failed: " << GetLastError() << std::endl;
RETURN(FALSE);
}
std::string strHash = GetHexRepresentation(byteFinalHash, dwFinalHashSize);
std::wostringstream filename;
filename << outputDir << strHash.c_str() << ".der" <<std::ends;
FILE* f = _wfopen(filename.str().c_str(), L"wb+");
if(!f)
{
std::wcout << "Failed to open file for writing: " << filename.str().c_str() << std::endl;
RETURN(FALSE);
}
int bytesWritten = fwrite(pPrevCertContext->pbCertEncoded, 1, pPrevCertContext->cbCertEncoded, f);
fclose(f);
if(bytesWritten != pPrevCertContext->cbCertEncoded)
{
std::cout << "Failed to write file" << std::endl;
RETURN(FALSE);
}
RETURN(TRUE);
}
//usage: DumpCertsFromSst <output directory> <SST file 1> ... <SST file n>
int _tmain(int argc, _TCHAR* argv[])
{
SECURITY_ATTRIBUTES sa;
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
if(argc < 3)
{
std::cout << "At least two arguments must be provided: outputDirectory sstFile1 ... sstFileN etc" << std::endl;
return 0;
}
TCHAR* outputDir = argv[1];
for(int ii = 2; ii < argc; ++ii)
{
HANDLE hFile = NULL;
HCERTSTORE hFileStore = NULL;
LPCWSTR pszFileName = argv[ii];
//Open file
hFile = CreateFile(pszFileName, GENERIC_READ, 0, &sa, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(INVALID_HANDLE_VALUE == hFile)
{
std::wcout << "Failed to open file: " << pszFileName << std::endl;
continue;
}
else
{
std::wcout << "Processing file: " << pszFileName << std::endl;
}
//open certificate store
hFileStore = CertOpenStore(CERT_STORE_PROV_FILE, 0, NULL, CERT_STORE_READONLY_FLAG, hFile);
if(NULL == hFileStore)
{
CloseHandle(hFile);
continue;
}
int count = 0;
PCCERT_CONTEXT pPrevCertContext = NULL;
pPrevCertContext = CertEnumCertificatesInStore(hFileStore, pPrevCertContext);
while(NULL != pPrevCertContext)
{
if(WriteToFileWithHashAsFilename(pPrevCertContext, outputDir))
++count;
pPrevCertContext = CertEnumCertificatesInStore(hFileStore, pPrevCertContext);
}
std::wcout << "Wrote " << count << " certificates" << std::endl;
CloseHandle(hFile);
CertCloseStore(hFileStore, 0);
}
return 1;
}

Resources