/*++ XcOpenProcessFile API Description: Opens a handle to a remote XCompute processes working File. Using this handle, an application can read remote files written by a XCompute process on a given Node. Writing of files is not supported. Local files can be written using Ordinary Windows file I/O (restricted to the working directory and Its children). Arguments: hSession Handle to an XCompute session associated with this call. fileUri the fully qualified file Uri (UTF-8) obtained by calling the XcGetProcessFileUri API. Flags Reserved. Must be 0. phFileHandle The returned handle to the opened file. Set to NULL if error pAsyncInfo The async info structure. Its an alias to the CS_ASYNC_INFO defined in Cosmos.h. If this parameter is NULL, then the function completes in synchronous manner and error code is returned as return value. If parameter is not NULL then the operation is carried on in asynchronous manner. If an asynchronous operation has been successfully started then this function terminates immediately with an HRESULT_FROM_WIN32(ERROR_IO_PENDING) return value. Any other return value indicates that it was impossible to start the asynchronous operation. Return Value: if pAsyncInfo is NULL CsError_OK indicates call succeeded Any other error code, indicates the failure reason. if pAsyncInfo != NULL HRESULT_FROM_WIN32(ERROR_IO_PENDING) indicates the async operation was successfully started Any other return value indicates it was impossible to start asynchronous operation (a SUCCESS HRESULT will never be returned if pAsyncInfo is not NULL). --*/ XCOMPUTEAPI_EXT XCERROR XCOMPUTEAPI XcOpenProcessFile( IN XCSESSIONHANDLE hSession, IN PCSTR fileUri, IN DWORD Flags, OUT PXCPROCESSFILEHANDLE phFileHandle, IN PCXC_ASYNC_INFO pAsyncInfo ) { PASYNC async; CAPTURE_ASYNC(async); // // Our file URI is a UNC path so we can just open it directly // HANDLE hFile = ::CreateFileA(fileUri, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { return COMPLETE_ASYNC(async,HRESULT_FROM_WIN32(GetLastError())); } *phFileHandle = (XCPROCESSFILEHANDLE)hFile; return COMPLETE_ASYNC(async, S_OK); }
/*++ XcReadProcessFile API Description: Reads the content of the file opened by the XcOpenProcessFile Arguments: phFileHandle The handle to the opened file. pBuffer Pointer to the buffer that receives the data read. pBytesRead Pointer to variable containing size of the buffer on input. On return this variable receives number of bytes read. pReadPosition The offset from the beginning of the file at which to read. pAsyncInfo The async info structure. Its an alias to the CS_ASYNC_INFO defined in Cosmos.h. If this parameter is NULL, then the function completes in synchronous manner and error code is returned as return value. If parameter is not NULL then the operation is carried on in asynchronous manner. If an asynchronous operation has been successfully started then this function terminates immediately with an HRESULT_FROM_WIN32(ERROR_IO_PENDING) return value. Any other return value indicates that it was impossible to start the asynchronous operation. Return Value: if pAsyncInfo is NULL CsError_OK indicates call succeeded Any other error code, indicates the failure reason. if pAsyncInfo != NULL HRESULT_FROM_WIN32(ERROR_IO_PENDING) indicates the async operation was successfully started Any other return value indicates it was impossible to start asynchronous operation (a SUCCESS HRESULT will never be returned if pAsyncInfo is not NULL). --*/ XCOMPUTEAPI_EXT XCERROR XCOMPUTEAPI XcReadProcessFile( IN XCPROCESSFILEHANDLE phFileHandle, OUT PVOID pBuffer, IN OUT PSIZE_T pBytesRead, IN OUT XCPROCESSFILEPOSITION* pReadPosition, IN PCXC_ASYNC_INFO pAsyncInfo ) { OVERLAPPED ov = {0}; PASYNC async; if (*pBytesRead > (DWORD)-1) { return E_NOTIMPL; } CAPTURE_ASYNC(async); ov.Offset = (DWORD)(*pReadPosition); ov.OffsetHigh = (DWORD)(*pReadPosition >> 32); if (!::ReadFile((HANDLE)phFileHandle, pBuffer, (DWORD)*pBytesRead, (LPDWORD)pBytesRead, &ov)) { return COMPLETE_ASYNC(async,HRESULT_FROM_WIN32(GetLastError())); } return COMPLETE_ASYNC(async, S_OK); }
void i2p_stream::start_read_line(error_code const& e, boost::shared_ptr<handler_type> h) { TORRENT_ASSERT(m_magic == 0x1337); COMPLETE_ASYNC("i2p_stream::start_read_line"); if (handle_error(e, h)) return; ADD_OUTSTANDING_ASYNC("i2p_stream::read_line"); m_buffer.resize(1); async_read(m_sock, boost::asio::buffer(m_buffer) , boost::bind(&i2p_stream::read_line, this, _1, h)); }
void upnp::resend_request(error_code const& ec) { TORRENT_ASSERT(is_single_thread()); COMPLETE_ASYNC("upnp::resend_request"); if (ec) return; boost::shared_ptr<upnp> me(self()); if (m_closing) return; if (m_retry_count < 12 && (m_devices.empty() || m_retry_count < 4)) { discover_device_impl(); return; } if (m_devices.empty()) { disable(errors::no_router); return; } for (std::set<rootdevice>::iterator i = m_devices.begin() , end(m_devices.end()); i != end; ++i) { if (i->control_url.empty() && !i->upnp_connection && !i->disabled) { // we don't have a WANIP or WANPPP url for this device, // ask for it rootdevice& d = const_cast<rootdevice&>(*i); TORRENT_ASSERT(d.magic == 1337); TORRENT_TRY { char msg[500]; snprintf(msg, sizeof(msg), "connecting to: %s", d.url.c_str()); log(msg); if (d.upnp_connection) d.upnp_connection->close(); d.upnp_connection.reset(new http_connection(m_io_service , m_resolver , boost::bind(&upnp::on_upnp_xml, self(), _1, _2 , boost::ref(d), _5))); d.upnp_connection->get(d.url, seconds(30), 1); } TORRENT_CATCH (std::exception& exc) { TORRENT_DECLARE_DUMMY(std::exception, exc); char msg[500]; snprintf(msg, sizeof(msg), "connection failed to: %s %s", d.url.c_str(), exc.what()); log(msg); d.disabled = true; } }
void i2p_connection::on_sam_connect(error_code const& ec, i2p_stream::handler_type const& h, boost::shared_ptr<i2p_stream>) { COMPLETE_ASYNC("i2p_stream::on_sam_connect"); m_state = sam_idle; if (ec) { h(ec); return; } do_name_lookup("ME", boost::bind(&i2p_connection::set_local_endpoint, this, _1, _2, h)); }
void i2p_stream::connected(error_code const& e, boost::shared_ptr<handler_type> h) { TORRENT_ASSERT(m_magic == 0x1337); COMPLETE_ASYNC("i2p_stream::connected"); if (handle_error(e, h)) return; // send hello command m_state = read_hello_response; static const char cmd[] = "HELLO VERSION MIN=3.0 MAX=3.0\n"; ADD_OUTSTANDING_ASYNC("i2p_stream::start_read_line"); async_write(m_sock, boost::asio::buffer(cmd, sizeof(cmd) - 1) , boost::bind(&i2p_stream::start_read_line, this, _1, h)); // fprintf(stderr, ">>> %s", cmd); }
void timeout_handler::timeout_callback(error_code const& error) { COMPLETE_ASYNC("timeout_handler::timeout_callback"); #if TORRENT_USE_ASSERTS TORRENT_ASSERT(m_outstanding_timer_wait > 0); --m_outstanding_timer_wait; #endif if (m_abort) return; time_point now = clock_type::now(); time_duration receive_timeout = now - m_read_time; time_duration completion_timeout = now - m_start_time; if ((m_read_timeout && m_read_timeout <= total_seconds(receive_timeout)) || (m_completion_timeout && m_completion_timeout <= total_seconds(completion_timeout)) || error) { on_timeout(error); return; } int timeout = 0; if (m_read_timeout > 0) timeout = m_read_timeout; if (m_completion_timeout > 0) { timeout = timeout == 0 ? int(m_completion_timeout - total_seconds(m_read_time - m_start_time)) : (std::min)(int(m_completion_timeout - total_seconds(m_read_time - m_start_time)), timeout); } ADD_OUTSTANDING_ASYNC("timeout_handler::timeout_callback"); error_code ec; m_timeout.expires_at(m_read_time + seconds(timeout), ec); m_timeout.async_wait( std::bind(&timeout_handler::timeout_callback, shared_from_this(), _1)); #if TORRENT_USE_ASSERTS ++m_outstanding_timer_wait; #endif }
void i2p_stream::read_line(error_code const& e, boost::shared_ptr<handler_type> h) { TORRENT_ASSERT(m_magic == 0x1337); COMPLETE_ASYNC("i2p_stream::read_line"); if (handle_error(e, h)) return; int read_pos = int(m_buffer.size()); // look for \n which means end of the response if (m_buffer[read_pos - 1] != '\n') { ADD_OUTSTANDING_ASYNC("i2p_stream::read_line"); // read another byte from the socket m_buffer.resize(read_pos + 1); async_read(m_sock, boost::asio::buffer(&m_buffer[read_pos], 1) , boost::bind(&i2p_stream::read_line, this, _1, h)); return; } m_buffer[read_pos - 1] = 0; if (m_command == cmd_incoming) { // this is the line containing the destination // of the incoming connection in an accept call m_dest = &m_buffer[0]; (*h)(e); std::vector<char>().swap(m_buffer); return; } error_code invalid_response(i2p_error::parse_failed , get_i2p_category()); // null-terminate the string and parse it m_buffer.push_back(0); char* ptr = &m_buffer[0]; char* next = ptr; char const* expect1 = 0; char const* expect2 = 0; switch (m_state) { case read_hello_response: expect1 = "HELLO"; expect2 = "REPLY"; break; case read_connect_response: case read_accept_response: expect1 = "STREAM"; expect2 = "STATUS"; break; case read_session_create_response: expect1 = "SESSION"; expect2 = "STATUS"; break; case read_name_lookup_response: expect1 = "NAMING"; expect2 = "REPLY"; break; } // fprintf(stderr, "<<< %s\n", &m_buffer[0]); ptr = string_tokenize(next, ' ', &next); if (ptr == 0 || expect1 == 0 || strcmp(expect1, ptr)) { handle_error(invalid_response, h); return; } ptr = string_tokenize(next, ' ', &next); if (ptr == 0 || expect2 == 0 || strcmp(expect2, ptr)) { handle_error(invalid_response, h); return; } int result = 0; // char const* message = 0; // float version = 3.0f; for(;;) { char* name = string_tokenize(next, '=', &next); if (name == 0) break; // fprintf(stderr, "name=\"%s\"\n", name); char* ptr2 = string_tokenize(next, ' ', &next); if (ptr2 == 0) { handle_error(invalid_response, h); return; } // fprintf(stderr, "value=\"%s\"\n", ptr2); if (strcmp("RESULT", name) == 0) { if (strcmp("OK", ptr2) == 0) result = i2p_error::no_error; else if (strcmp("CANT_REACH_PEER", ptr2) == 0) result = i2p_error::cant_reach_peer; else if (strcmp("I2P_ERROR", ptr2) == 0) result = i2p_error::i2p_error; else if (strcmp("INVALID_KEY", ptr2) == 0) result = i2p_error::invalid_key; else if (strcmp("INVALID_ID", ptr2) == 0) result = i2p_error::invalid_id; else if (strcmp("TIMEOUT", ptr2) == 0) result = i2p_error::timeout; else if (strcmp("KEY_NOT_FOUND", ptr2) == 0) result = i2p_error::key_not_found; else if (strcmp("DUPLICATED_ID", ptr2) == 0) result = i2p_error::duplicated_id; else result = i2p_error::num_errors; // unknown error } else if (strcmp("MESSAGE", name) == 0) { // message = ptr2; } else if (strcmp("VERSION", name) == 0) { // version = float(atof(ptr2)); } else if (strcmp("VALUE", name) == 0) { m_name_lookup = ptr2; } else if (strcmp("DESTINATION", name) == 0) { m_dest = ptr2; } } error_code ec(result, get_i2p_category()); switch (result) { case i2p_error::no_error: case i2p_error::invalid_key: break; default: { handle_error (ec, h); return; } } switch (m_state) { case read_hello_response: switch (m_command) { case cmd_create_session: send_session_create(h); break; case cmd_accept: send_accept(h); break; case cmd_connect: send_connect(h); break; default: (*h)(e); std::vector<char>().swap(m_buffer); } break; case read_connect_response: case read_session_create_response: case read_name_lookup_response: (*h)(ec); std::vector<char>().swap(m_buffer); break; case read_accept_response: // the SAM bridge is waiting for an incoming // connection. // wait for one more line containing // the destination of the remote peer m_command = cmd_incoming; m_buffer.resize(1); ADD_OUTSTANDING_ASYNC("i2p_stream::read_line"); async_read(m_sock, boost::asio::buffer(m_buffer) , boost::bind(&i2p_stream::read_line, this, _1, h)); break; } return; }