////////////////////////////////////////////////////////////////////////// // Create: create a new console (logger) with the following OPTIONAL attributes: // // lpszWindowTitle : window title // buffer_size_x : width // buffer_size_y : height // logger_name : pipe name . the default is f(this,time) // helper_executable: which (and where) is the EXE that will write the pipe's output ////////////////////////////////////////////////////////////////////////// long CConsoleLogger::Create(const char *lpszWindowTitle/*=NULL*/, int buffer_size_x/*=-1*/,int buffer_size_y/*=-1*/, const char *logger_name/*=NULL*/, const char *helper_executable/*=NULL*/) { // Ensure there's no pipe connected if (m_hPipe != INVALID_HANDLE_VALUE) { DisconnectNamedPipe(m_hPipe); CloseHandle(m_hPipe); m_hPipe=INVALID_HANDLE_VALUE; } strcpy(m_name,"\\\\.\\pipe\\"); if (!logger_name) { // no name was give , create name based on the current address+time // (you can modify it to use PID , rand() ,... unsigned long now = GetTickCount(); logger_name = m_name+ strlen(m_name); sprintf((char*)logger_name,"logger%d_%lu",(int)this,now); } else { // just use the given name strcat(m_name,logger_name); } // Create the pipe m_hPipe = CreateNamedPipe( m_name, // pipe name PIPE_ACCESS_OUTBOUND, // read/write access, we're only writing... PIPE_TYPE_MESSAGE | // message type pipe PIPE_READMODE_BYTE| // message-read mode PIPE_WAIT, // blocking mode 1, // max. instances 4096, // output buffer size 0, // input buffer size (we don't read data, so 0 is fine) 1, // client time-out NULL); // no security attribute if (m_hPipe==INVALID_HANDLE_VALUE) { // failure MessageBox(NULL,"CreateNamedPipe failed","ConsoleLogger failed",MB_OK); return -1; } // Extra console : create another process , it's role is to display the pipe's output STARTUPINFO si; PROCESS_INFORMATION pi; GetStartupInfo(&si); char cmdline[MAX_PATH];; if (!helper_executable) helper_executable=DEFAULT_HELPER_EXE; sprintf(cmdline,"%s %s",helper_executable,logger_name); BOOL bRet = CreateProcess(NULL,cmdline,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi); if (!bRet) { // on failure - try to get the path from the environment char *path = getenv("ConsoleLoggerHelper"); if (path) { sprintf(cmdline,"%s %s",path,logger_name); bRet = CreateProcess(NULL,cmdline,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi); } if (!bRet) { MessageBox(NULL,"Helper executable not found","ConsoleLogger failed",MB_OK); CloseHandle(m_hPipe); m_hPipe = INVALID_HANDLE_VALUE; return -1; } } BOOL bConnected = ConnectNamedPipe(m_hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); if (!bConnected) { MessageBox(NULL,"ConnectNamedPipe failed","ConsoleLogger failed",MB_OK); CloseHandle(m_hPipe); m_hPipe = INVALID_HANDLE_VALUE; return -1; } DWORD cbWritten; ////////////////////////////////////////////////////////////////////////// // In order to easily add new future-features , i've chosen to pass the "extra" // parameters just the HTTP protocol - via textual "headers" . // the last header should end with NULL ////////////////////////////////////////////////////////////////////////// char buffer[128]; // Send title if (!lpszWindowTitle) lpszWindowTitle=m_name+9; sprintf(buffer,"TITLE: %s\r\n",lpszWindowTitle); WriteFile(m_hPipe,buffer,strlen(buffer),&cbWritten,NULL); if (cbWritten!=strlen(buffer)) { MessageBox(NULL,"WriteFile failed(1)","ConsoleLogger failed",MB_OK); DisconnectNamedPipe(m_hPipe); CloseHandle(m_hPipe); m_hPipe=INVALID_HANDLE_VALUE; return -1; } if (buffer_size_x!=-1 && buffer_size_y!=-1) { // Send buffer-size sprintf(buffer,"BUFFER-SIZE: %dx%d\r\n",buffer_size_x,buffer_size_y); WriteFile(m_hPipe,buffer,strlen(buffer),&cbWritten,NULL); if (cbWritten!=strlen(buffer)) { MessageBox(NULL,"WriteFile failed(2)","ConsoleLogger failed",MB_OK); DisconnectNamedPipe(m_hPipe); CloseHandle(m_hPipe); m_hPipe=INVALID_HANDLE_VALUE; return -1; } } // Send more headers. you can override the AddHeaders() function to // extend this class if (AddHeaders()) { DisconnectNamedPipe(m_hPipe); CloseHandle(m_hPipe); m_hPipe=INVALID_HANDLE_VALUE; return -1; } // send NULL as "end of header" buffer[0]=0; WriteFile(m_hPipe,buffer,1,&cbWritten,NULL); if (cbWritten!=1) { MessageBox(NULL,"WriteFile failed(3)","ConsoleLogger failed",MB_OK); DisconnectNamedPipe(m_hPipe); CloseHandle(m_hPipe); m_hPipe=INVALID_HANDLE_VALUE; return -1; } return 0; }
co_rc_t co_os_pipe_server_create_client(co_os_pipe_server_t *ps, HANDLE handle) { char pipename[0x100]; co_os_pipe_connection_t *connection; HANDLE event; int index; co_rc_t rc = CO_RC(OK); pipe_server_pathname(pipename, sizeof(pipename), ps->id); if (CO_OS_PIPE_SERVER_MAX_CLIENTS == ps->num_clients) { rc = CO_RC(ERROR); goto out; } connection = co_os_malloc(sizeof(*connection)); if (connection == NULL) { rc = CO_RC(ERROR); goto out; } memset(connection, 0, sizeof(*connection)); connection->in_buffer = (char *)co_os_malloc(CO_OS_PIPE_SERVER_BUFFER_SIZE); if (connection->in_buffer == NULL) { rc = CO_RC(ERROR); goto out_free_connection; } connection->buffer_size = CO_OS_PIPE_SERVER_BUFFER_SIZE; event = CreateEvent(NULL, TRUE, FALSE, NULL); if (event == INVALID_HANDLE_VALUE) { rc = CO_RC(ERROR); goto out_free_buffer; } ResetEvent(event); if (handle) { connection->pipe = handle; } else { connection->pipe = CreateNamedPipe( pipename, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0x100000, 0x100000, 10000, NULL); } if (connection->pipe == INVALID_HANDLE_VALUE) { rc = CO_RC(ERROR); goto out_close_event; } index = ps->num_clients; connection->overlap.hEvent = event; connection->index = index; ps->num_clients++; ps->clients[index] = connection; ps->events[index] = event; if (ConnectNamedPipe(connection->pipe, &connection->overlap) != 0) { co_os_pipe_server_client_connected(ps, connection); rc = co_os_pipe_server_read_sync(ps, connection); } else { connection->state = CO_OS_PIPE_SERVER_STATE_NOT_CONNECTED; } return rc; /* error path */ out_close_event: CloseHandle(event); out_free_buffer: co_os_free(connection->in_buffer); out_free_connection: co_os_free(connection); out: return rc; }
// Creates named pipes for stdout, stderr, stdin BOOL CreateStdPipes( xCmdMessage* pMsg, STARTUPINFO* psi ) { SECURITY_ATTRIBUTES SecAttrib = {0}; SECURITY_DESCRIPTOR SecDesc; InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&SecDesc, TRUE, NULL, FALSE); SecAttrib.nLength = sizeof(SECURITY_ATTRIBUTES); SecAttrib.lpSecurityDescriptor = &SecDesc;; SecAttrib.bInheritHandle = TRUE; psi->dwFlags |= STARTF_USESTDHANDLES; psi->hStdOutput = INVALID_HANDLE_VALUE; psi->hStdInput = INVALID_HANDLE_VALUE; psi->hStdError = INVALID_HANDLE_VALUE; // StdOut pipe name _stprintf( szStdOutPipe, _T("\\\\.\\pipe\\%s%s%d"), XCMDSTDOUT, pMsg->szMachine, pMsg->dwProcessId ); // StdIn pipe name _stprintf( szStdInPipe, _T("\\\\.\\pipe\\%s%s%d"), XCMDSTDIN, pMsg->szMachine, pMsg->dwProcessId ); // StdError pipe name _stprintf( szStdErrPipe, _T("\\\\.\\pipe\\%s%s%d"), XCMDSTDERR, pMsg->szMachine, pMsg->dwProcessId ); // Create StdOut pipe psi->hStdOutput = CreateNamedPipe( szStdOutPipe, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, (DWORD)-1, &SecAttrib); // Create StdError pipe psi->hStdError = CreateNamedPipe( szStdErrPipe, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, (DWORD)-1, &SecAttrib); // Create StdIn pipe psi->hStdInput = CreateNamedPipe( szStdInPipe, PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, (DWORD)-1, &SecAttrib); if ( psi->hStdOutput == INVALID_HANDLE_VALUE || psi->hStdError == INVALID_HANDLE_VALUE || psi->hStdInput == INVALID_HANDLE_VALUE ) { CloseHandle( psi->hStdOutput ); CloseHandle( psi->hStdError ); CloseHandle( psi->hStdInput ); return FALSE; } // Waiting for client to connect to this pipe ConnectNamedPipe( psi->hStdOutput, NULL ); ConnectNamedPipe( psi->hStdInput, NULL ); ConnectNamedPipe( psi->hStdError, NULL ); return TRUE; }
/* Run a command and redirect its input and output handles to a pair of anonymous pipes. The process handle and pipe handles are returned in the info struct. Returns the PID of the new process, or -1 on error. */ static int run_command_redirected(char *cmdexec, struct subprocess_info *info) { /* Each named pipe we create has to have a unique name. */ static int pipe_serial_no = 0; char pipe_name[32]; SECURITY_ATTRIBUTES sa; STARTUPINFO si; PROCESS_INFORMATION pi; setup_environment(&info->fdn); /* Make the pipe handles inheritable. */ sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; /* The child's input pipe is an ordinary blocking pipe. */ if (CreatePipe(&info->child_in_r, &info->child_in_w, &sa, 0) == 0) { if (o.verbose) logdebug("Error in CreatePipe: %d\n", GetLastError()); return -1; } /* Pipe names must have this special form. */ Snprintf(pipe_name, sizeof(pipe_name), "\\\\.\\pipe\\ncat-%d-%d", GetCurrentProcessId(), pipe_serial_no); if (o.debug > 1) logdebug("Creating named pipe \"%s\"\n", pipe_name); /* The output pipe has to be nonblocking, which requires this complicated setup. */ info->child_out_r = CreateNamedPipe(pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, 1, 4096, 4096, 1000, &sa); if (info->child_out_r == 0) { if (o.verbose) logdebug("Error in CreateNamedPipe: %d\n", GetLastError()); CloseHandle(info->child_in_r); CloseHandle(info->child_in_w); return -1; } info->child_out_w = CreateFile(pipe_name, GENERIC_WRITE, 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (info->child_out_w == 0) { CloseHandle(info->child_in_r); CloseHandle(info->child_in_w); CloseHandle(info->child_out_r); return -1; } pipe_serial_no++; /* Don't inherit our end of the pipes. */ SetHandleInformation(info->child_in_w, HANDLE_FLAG_INHERIT, 0); SetHandleInformation(info->child_out_r, HANDLE_FLAG_INHERIT, 0); memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.hStdInput = info->child_in_r; si.hStdOutput = info->child_out_w; si.hStdError = GetStdHandle(STD_ERROR_HANDLE); si.dwFlags |= STARTF_USESTDHANDLES; memset(&pi, 0, sizeof(pi)); if (CreateProcess(NULL, cmdexec, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) == 0) { if (o.verbose) logdebug("Error in CreateProcess: %d\n", GetLastError()); CloseHandle(info->child_in_r); CloseHandle(info->child_in_w); CloseHandle(info->child_out_r); CloseHandle(info->child_out_w); return -1; } /* Close hThread here because we have no use for it. hProcess is closed in subprocess_info_close. */ CloseHandle(pi.hThread); info->proc = pi.hProcess; return pi.dwProcessId; }
/* *-------------------------------------------------------------- * * OS_LibInit -- * * Set up the OS library for use. * * Results: * Returns 0 if success, -1 if not. * * Side effects: * Sockets initialized, pseudo file descriptors setup, etc. * *-------------------------------------------------------------- */ int OS_LibInit(int stdioFds[3]) { WORD wVersion; WSADATA wsaData; int err; int fakeFd; char *cLenPtr = NULL; char *val = NULL; // char * abc; // int nTestFcgi; char namepipe[256]; if(libInitialized) return 0; InitializeCriticalSection(&fdTableCritical); /* * Initialize windows sockets library. */ wVersion = MAKEWORD(2,0); err = WSAStartup( wVersion, &wsaData ); if (err) { fprintf(stderr, "Error starting Windows Sockets. Error: %d", WSAGetLastError()); exit(111); } /* * Create the I/O completion port to be used for our I/O queue. */ if (hIoCompPort == INVALID_HANDLE_VALUE) { hIoCompPort = CreateIoCompletionPort (INVALID_HANDLE_VALUE, NULL, 0, 1); if(hIoCompPort == INVALID_HANDLE_VALUE) { printf("<H2>OS_LibInit Failed CreateIoCompletionPort! ERROR: %d</H2>\r\n\r\n", GetLastError()); return -1; } } /* * If a shutdown event is in the env, save it (I don't see any to * remove it from the environment out from under the application). * Spawn a thread to wait on the shutdown request. */ val = getenv(SHUTDOWN_EVENT_NAME); if (val != NULL) { HANDLE shutdownEvent = (HANDLE) atoi(val); if (_beginthread(ShutdownRequestThread, 0, shutdownEvent) == -1) { return -1; } } if (acceptMutex == INVALID_HANDLE_VALUE) { /* If an accept mutex is in the env, use it */ val = getenv(MUTEX_VARNAME); if (val != NULL) { acceptMutex = (HANDLE) atoi(val); } } /* * Determine if this library is being used to listen for FastCGI * connections. This is communicated by STDIN containing a * valid handle to a listener object. In this case, both the * "stdout" and "stderr" handles will be INVALID (ie. closed) by * the starting process. * * The trick is determining if this is a pipe or a socket... * * XXX: Add the async accept test to determine socket or handle to a * pipe!!! */ if((GetStdHandle(STD_OUTPUT_HANDLE) == INVALID_HANDLE_VALUE) && (GetStdHandle(STD_ERROR_HANDLE) == INVALID_HANDLE_VALUE) && (GetStdHandle(STD_INPUT_HANDLE) != INVALID_HANDLE_VALUE) ) { DWORD pipeMode = PIPE_READMODE_BYTE | PIPE_WAIT; HANDLE oldStdIn = GetStdHandle(STD_INPUT_HANDLE); // Move the handle to a "low" number if (! DuplicateHandle(GetCurrentProcess(), oldStdIn, GetCurrentProcess(), &hListen, 0, TRUE, DUPLICATE_SAME_ACCESS)) { return -1; } if (! SetStdHandle(STD_INPUT_HANDLE, hListen)) { return -1; } CloseHandle(oldStdIn); //OutputDebugString("CloseHandle(oldStdIn);\n"); #ifdef DEBUG_CGI //OutputDebugString("in DEBUG_CGI \n"); sprintf(namepipe,"%s\\%d","\\\\.\\pipe\\FastCGI\\dynamic",getpid()); //OutputDebugString(namepipe); hListen=CreateNamedPipe( //"\\\\.\\pipe\\FastCGI\\dynamic\\abc", // pipe name namepipe, PIPE_ACCESS_DUPLEX, // read/write access PIPE_TYPE_MESSAGE | // message type pipe PIPE_READMODE_MESSAGE | // message-read mode PIPE_WAIT, // blocking mode PIPE_UNLIMITED_INSTANCES, // max. instances 4096, // output buffer size 4096, // input buffer size NMPWAIT_USE_DEFAULT_WAIT, // client time-out NULL); #endif /* * Set the pipe handle state so that it operates in wait mode. * * NOTE: The listenFd is not mapped to a pseudo file descriptor * as all work done on it is contained to the OS library. * * XXX: Initial assumption is that SetNamedPipeHandleState will * fail if this is an IP socket... */ if (SetNamedPipeHandleState(hListen, &pipeMode, NULL, NULL)) { listenType = FD_PIPE_SYNC; } else { listenType = FD_SOCKET_SYNC; } } /* * If there are no stdioFds passed in, we're done. */ if(stdioFds == NULL) { libInitialized = 1; return 0; } /* * Setup standard input asynchronous I/O. There is actually a separate * thread spawned for this purpose. The reason for this is that some * web servers use anonymous pipes for the connection between itself * and a CGI application. Anonymous pipes can't perform asynchronous * I/O or use I/O completion ports. Therefore in order to present a * consistent I/O dispatch model to an application we emulate I/O * completion port behavior by having the standard input thread posting * messages to the hIoCompPort which look like a complete overlapped * I/O structure. This keeps the event dispatching simple from the * application perspective. */ stdioHandles[STDIN_FILENO] = GetStdHandle(STD_INPUT_HANDLE); if(!SetHandleInformation(stdioHandles[STDIN_FILENO], HANDLE_FLAG_INHERIT, 0)) { /* * XXX: Causes error when run from command line. Check KB err = GetLastError(); DebugBreak(); exit(99); */ } if ((fakeFd = Win32NewDescriptor(FD_PIPE_SYNC, (int)stdioHandles[STDIN_FILENO], STDIN_FILENO)) == -1) { return -1; } else { /* * Set stdin equal to our pseudo FD and create the I/O completion * port to be used for async I/O. */ stdioFds[STDIN_FILENO] = fakeFd; } /* * Create the I/O completion port to be used for communicating with * the thread doing I/O on standard in. This port will carry read * and possibly thread termination requests to the StdinThread. */ if (hStdinCompPort == INVALID_HANDLE_VALUE) { hStdinCompPort = CreateIoCompletionPort (INVALID_HANDLE_VALUE, NULL, 0, 1); if(hStdinCompPort == INVALID_HANDLE_VALUE) { printf("<H2>OS_LibInit Failed CreateIoCompletionPort: STDIN! ERROR: %d</H2>\r\n\r\n", GetLastError()); return -1; } } /* * Create the thread that will read stdin if the CONTENT_LENGTH * is non-zero. */ if((cLenPtr = getenv("CONTENT_LENGTH")) != NULL && atoi(cLenPtr) > 0) { hStdinThread = (HANDLE) _beginthread(StdinThread, 0, NULL); if (hStdinThread == (HANDLE) -1) { printf("<H2>OS_LibInit Failed to create STDIN thread! ERROR: %d</H2>\r\n\r\n", GetLastError()); return -1; } } /* * STDOUT will be used synchronously. * * XXX: May want to convert this so that it could be used for OVERLAPPED * I/O later. If so, model it after the Stdin I/O as stdout is * also incapable of async I/O on some servers. */ stdioHandles[STDOUT_FILENO] = GetStdHandle(STD_OUTPUT_HANDLE); if(!SetHandleInformation(stdioHandles[STDOUT_FILENO], HANDLE_FLAG_INHERIT, FALSE)) { DebugBreak(); exit(99); } if ((fakeFd = Win32NewDescriptor(FD_PIPE_SYNC, (int)stdioHandles[STDOUT_FILENO], STDOUT_FILENO)) == -1) { return -1; } else { /* * Set stdout equal to our pseudo FD */ stdioFds[STDOUT_FILENO] = fakeFd; } stdioHandles[STDERR_FILENO] = GetStdHandle(STD_ERROR_HANDLE); if(!SetHandleInformation(stdioHandles[STDERR_FILENO], HANDLE_FLAG_INHERIT, FALSE)) { DebugBreak(); exit(99); } if ((fakeFd = Win32NewDescriptor(FD_PIPE_SYNC, (int)stdioHandles[STDERR_FILENO], STDERR_FILENO)) == -1) { return -1; } else { /* * Set stderr equal to our pseudo FD */ stdioFds[STDERR_FILENO] = fakeFd; } return 0; }
void ConnectionListener::run() { HANDLE hPipe; OVERLAPPED oOverlap; DWORD cbBytesRead; memset(&oOverlap, 0, sizeof(OVERLAPPED)); d->hEvent = CreateEvent(NULL, true, false, NULL); oOverlap.hEvent = d->hEvent; bool recreate = true; while (1) { BOOL alreadyConnected = false; if (recreate) { hPipe = CreateNamedPipe( (const wchar_t *)d->pipename.c_str(), // pipe name PIPE_ACCESS_DUPLEX | // read/write access FILE_FLAG_OVERLAPPED, //Overlapped mode PIPE_TYPE_MESSAGE | // message type pipe PIPE_READMODE_MESSAGE | // message-read mode PIPE_WAIT, // blocking mode PIPE_UNLIMITED_INSTANCES, // max. instances BUFSIZE, // output buffer size BUFSIZE, // input buffer size 0, // client time-out &d->sa); // default security attribute if (hPipe == INVALID_HANDLE_VALUE) { return; } ConnectNamedPipe(hPipe, &oOverlap); alreadyConnected = GetLastError() == ERROR_PIPE_CONNECTED; recreate = false; } if(!alreadyConnected){ DWORD result = WaitForSingleObject(oOverlap.hEvent, 1000); if (!d->running) { CancelIo(hPipe); WaitForSingleObject(oOverlap.hEvent, INFINITE); break; } if(result == WAIT_TIMEOUT){ //CloseHandle(hPipe); continue; } BOOL connected = GetOverlappedResult(hPipe, &oOverlap, &cbBytesRead, false); if (!connected) { CloseHandle(hPipe); return; } } ConnectionListenerEventData *data = new ConnectionListenerEventData(); ResetEvent(oOverlap.hEvent); data->socket = new TelldusCore::Socket(hPipe); d->waitEvent->signal(data); recreate = true; } CloseHandle(d->hEvent); CloseHandle(hPipe); }
static void named_pipe_accept_loop(const char *path) { HANDLE handles[2]; OVERLAPPED olap; HANDLE connected_event = CreateEvent(NULL, FALSE, TRUE, NULL); if (!connected_event) { w_log(W_LOG_ERR, "named_pipe_accept_loop: CreateEvent failed: %s\n", win32_strerror(GetLastError())); return; } listener_thread_event = CreateEvent(NULL, FALSE, TRUE, NULL); handles[0] = connected_event; handles[1] = listener_thread_event; memset(&olap, 0, sizeof(olap)); olap.hEvent = connected_event; w_log(W_LOG_ERR, "waiting for pipe clients on %s\n", path); while (!stopping) { w_stm_t stm; HANDLE client_fd; DWORD res; client_fd = CreateNamedPipe( path, PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE|PIPE_READMODE_BYTE| PIPE_REJECT_REMOTE_CLIENTS, PIPE_UNLIMITED_INSTANCES, WATCHMAN_IO_BUF_SIZE, 512, 0, NULL); if (client_fd == INVALID_HANDLE_VALUE) { w_log(W_LOG_ERR, "CreateNamedPipe(%s) failed: %s\n", path, win32_strerror(GetLastError())); continue; } ResetEvent(connected_event); if (!ConnectNamedPipe(client_fd, &olap)) { res = GetLastError(); if (res == ERROR_PIPE_CONNECTED) { goto good_client; } if (res != ERROR_IO_PENDING) { w_log(W_LOG_ERR, "ConnectNamedPipe: %s\n", win32_strerror(GetLastError())); CloseHandle(client_fd); continue; } res = WaitForMultipleObjectsEx(2, handles, false, INFINITE, true); if (res == WAIT_OBJECT_0 + 1) { // Signalled to stop CancelIoEx(client_fd, &olap); CloseHandle(client_fd); continue; } if (res == WAIT_OBJECT_0) { goto good_client; } w_log(W_LOG_ERR, "WaitForMultipleObjectsEx: ConnectNamedPipe: " "unexpected status %u\n", res); CancelIoEx(client_fd, &olap); CloseHandle(client_fd); } else { good_client: stm = w_stm_handleopen(client_fd); if (!stm) { w_log(W_LOG_ERR, "Failed to allocate stm for pipe handle: %s\n", strerror(errno)); CloseHandle(client_fd); continue; } make_new_client(stm); } } }
static void* named_pipe_server_thread(void* arg) { HANDLE hNamedPipe = NULL; BYTE* lpReadBuffer = NULL; BYTE* lpWriteBuffer = NULL; BOOL fSuccess = FALSE; BOOL fConnected = FALSE; DWORD nNumberOfBytesToRead; DWORD nNumberOfBytesToWrite; DWORD lpNumberOfBytesRead; DWORD lpNumberOfBytesWritten; hNamedPipe = CreateNamedPipe(lpszPipeNameMt, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0, NULL); if (!hNamedPipe) { printf("%s: CreateNamedPipe failure: NULL handle\n", __FUNCTION__); goto out; } if (hNamedPipe == INVALID_HANDLE_VALUE) { printf("%s: CreateNamedPipe failure: INVALID_HANDLE_VALUE\n", __FUNCTION__); goto out; } SetEvent(ReadyEvent); fConnected = ConnectNamedPipe(hNamedPipe, NULL); if (!fConnected) fConnected = (GetLastError() == ERROR_PIPE_CONNECTED); if (!fConnected) { printf("%s: ConnectNamedPipe failure\n", __FUNCTION__); goto out; } if (!(lpReadBuffer = (BYTE*) malloc(PIPE_BUFFER_SIZE))) { printf("%s: Error allocating read buffer\n", __FUNCTION__); goto out; } if (!(lpWriteBuffer = (BYTE*) malloc(PIPE_BUFFER_SIZE))) { printf("%s: Error allocating write buffer\n", __FUNCTION__); goto out; } lpNumberOfBytesRead = 0; nNumberOfBytesToRead = PIPE_BUFFER_SIZE; ZeroMemory(lpReadBuffer, PIPE_BUFFER_SIZE); if (!ReadFile(hNamedPipe, lpReadBuffer, nNumberOfBytesToRead, &lpNumberOfBytesRead, NULL) || lpNumberOfBytesRead != nNumberOfBytesToRead) { printf("%s: Server NamedPipe ReadFile failure\n", __FUNCTION__); goto out; } printf("Server ReadFile (%d):\n", lpNumberOfBytesRead); winpr_HexDump(lpReadBuffer, lpNumberOfBytesRead); lpNumberOfBytesWritten = 0; nNumberOfBytesToWrite = PIPE_BUFFER_SIZE; FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x45); if (!WriteFile(hNamedPipe, lpWriteBuffer, nNumberOfBytesToWrite, &lpNumberOfBytesWritten, NULL) || lpNumberOfBytesWritten != nNumberOfBytesToWrite) { printf("%s: Server NamedPipe WriteFile failure\n", __FUNCTION__); goto out; } fSuccess = TRUE; out: free(lpReadBuffer); free(lpWriteBuffer); CloseHandle(hNamedPipe); if (!fSuccess) testFailed = TRUE; return NULL; }
static void* named_pipe_single_thread(void* arg) { HANDLE servers[TESTNUMPIPESST]; HANDLE clients[TESTNUMPIPESST]; char sndbuf[PIPE_BUFFER_SIZE]; char rcvbuf[PIPE_BUFFER_SIZE]; DWORD dwRead; DWORD dwWritten; int i; int numPipes; BOOL bSuccess = FALSE; #ifndef _WIN32 WINPR_NAMED_PIPE* p; #endif numPipes = TESTNUMPIPESST; memset(servers, 0, sizeof(servers)); memset(clients, 0, sizeof(clients)); WaitForSingleObject(ReadyEvent, INFINITE); for (i = 0; i < numPipes; i++) { if (!(servers[i] = CreateNamedPipe(lpszPipeNameSt, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0, NULL))) { printf("%s: CreateNamedPipe #%d failed\n", __FUNCTION__, i); goto out; } } #ifndef _WIN32 for (i = 0; i < numPipes; i++) { p = (WINPR_NAMED_PIPE*)servers[i]; if (strcmp(lpszPipeNameSt, p->name)) { printf("%s: Pipe name mismatch for pipe #%d ([%s] instead of [%s])\n", __FUNCTION__, i, p->name, lpszPipeNameSt); goto out; } if (p->clientfd != -1) { printf("%s: Unexpected client fd value for pipe #%d (%d instead of -1)\n", __FUNCTION__, i, p->clientfd); goto out; } if (p->serverfd < 1) { printf("%s: Unexpected server fd value for pipe #%d (%d is not > 0)\n", __FUNCTION__, i, p->serverfd); goto out; } if (p->ServerMode == FALSE) { printf("%s: Unexpected ServerMode value for pipe #%d (0 instead of 1)\n", __FUNCTION__, i); goto out; } } #endif for (i = 0; i < numPipes; i++) { if (!(clients[i] = CreateFile(lpszPipeNameSt, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL))) { printf("%s: CreateFile #%d failed\n", __FUNCTION__, i); goto out; } if (!ConnectNamedPipe(servers[i], NULL)) { printf("%s: ConnectNamedPipe #%d failed\n", __FUNCTION__, i); goto out; } } #ifndef _WIN32 for (i = 0; i < numPipes; i++) { p = servers[i]; if (p->clientfd < 1) { printf("%s: Unexpected client fd value for pipe #%d (%d is not > 0)\n", __FUNCTION__, i, p->clientfd); goto out; } if (p->ServerMode) { printf("%s: Unexpected ServerMode value for pipe #%d (1 instead of 0)\n", __FUNCTION__, i); goto out; } } for (i = 0; i < numPipes; i++) { /* Test writing from clients to servers */ ZeroMemory(sndbuf, sizeof(sndbuf)); ZeroMemory(rcvbuf, sizeof(rcvbuf)); sprintf_s(sndbuf, sizeof(sndbuf), "CLIENT->SERVER ON PIPE #%05d", i); p = servers[i]; if (!WriteFile(clients[i], sndbuf, sizeof(sndbuf), &dwWritten, NULL) || dwWritten != sizeof(sndbuf)) { printf("%s: Error writing to client end of pipe #%d\n", __FUNCTION__, i); goto out; } if (!ReadFile(servers[i], rcvbuf, dwWritten, &dwRead, NULL) || dwRead != dwWritten) { printf("%s: Error reading on server end of pipe #%d\n", __FUNCTION__, i); goto out; } if (memcmp(sndbuf, rcvbuf, sizeof(sndbuf))) { printf("%s: Error data read on server end of pipe #%d is corrupted\n", __FUNCTION__, i); goto out; } /* Test writing from servers to clients */ ZeroMemory(sndbuf, sizeof(sndbuf)); ZeroMemory(rcvbuf, sizeof(rcvbuf)); sprintf_s(sndbuf, sizeof(sndbuf), "SERVER->CLIENT ON PIPE #%05d", i); p = servers[i]; if (!WriteFile(servers[i], sndbuf, sizeof(sndbuf), &dwWritten, NULL) || dwWritten != sizeof(sndbuf)) { printf("%s: Error writing to server end of pipe #%d\n", __FUNCTION__, i); goto out; } if (!ReadFile(clients[i], rcvbuf, dwWritten, &dwRead, NULL) || dwRead != dwWritten) { printf("%s: Error reading on client end of pipe #%d\n", __FUNCTION__, i); goto out; } if (memcmp(sndbuf, rcvbuf, sizeof(sndbuf))) { printf("%s: Error data read on client end of pipe #%d is corrupted\n", __FUNCTION__, i); goto out; } } #endif /** * After DisconnectNamedPipe on server end * ReadFile/WriteFile must fail on client end */ i = numPipes - 1; DisconnectNamedPipe(servers[i]); if (ReadFile(clients[i], rcvbuf, sizeof(rcvbuf), &dwRead, NULL)) { printf("%s: Error ReadFile on client should have failed after DisconnectNamedPipe on server\n", __FUNCTION__); goto out; } if (WriteFile(clients[i], sndbuf, sizeof(sndbuf), &dwWritten, NULL)) { printf("%s: Error WriteFile on client end should have failed after DisconnectNamedPipe on server\n", __FUNCTION__); goto out; } CloseHandle(servers[i]); CloseHandle(clients[i]); numPipes--; /** * After CloseHandle (without calling DisconnectNamedPipe first) on server end * ReadFile/WriteFile must fail on client end */ i = numPipes - 1; CloseHandle(servers[i]); if (ReadFile(clients[i], rcvbuf, sizeof(rcvbuf), &dwRead, NULL)) { printf("%s: Error ReadFile on client end should have failed after CloseHandle on server\n", __FUNCTION__); goto out; } if (WriteFile(clients[i], sndbuf, sizeof(sndbuf), &dwWritten, NULL)) { printf("%s: Error WriteFile on client end should have failed after CloseHandle on server\n", __FUNCTION__); goto out; } CloseHandle(clients[i]); numPipes--; /** * After CloseHandle on client end * ReadFile/WriteFile must fail on server end */ i = numPipes - 1; CloseHandle(clients[i]); if (ReadFile(servers[i], rcvbuf, sizeof(rcvbuf), &dwRead, NULL)) { printf("%s: Error ReadFile on server end should have failed after CloseHandle on client\n", __FUNCTION__); goto out; } if (WriteFile(clients[i], sndbuf, sizeof(sndbuf), &dwWritten, NULL)) { printf("%s: Error WriteFile on server end should have failed after CloseHandle on client\n", __FUNCTION__); goto out; } DisconnectNamedPipe(servers[i]); CloseHandle(servers[i]); numPipes--; /* Close all remaining pipes */ for (i = 0; i < numPipes; i++) { DisconnectNamedPipe(servers[i]); CloseHandle(servers[i]); CloseHandle(clients[i]); } numPipes = 0; bSuccess = TRUE; out: if (!bSuccess) testFailed = TRUE; return NULL; }
int main(int argc, char* argv[]) { HANDLE hPipe; hPipe = CreateNamedPipe( g_szPipeName, // pipe name PIPE_ACCESS_DUPLEX, // read/write access PIPE_TYPE_MESSAGE | // message type pipe PIPE_READMODE_MESSAGE | // message-read mode PIPE_WAIT, // blocking mode PIPE_UNLIMITED_INSTANCES, // max. instances BUFFER_SIZE, // output buffer size BUFFER_SIZE, // input buffer size NMPWAIT_USE_DEFAULT_WAIT, // client time-out NULL); // default security attribute if (INVALID_HANDLE_VALUE == hPipe) { printf("\nError occurred while creating the pipe: %d", GetLastError()); return 1; //Error } else { printf("\nCreateNamedPipe() was successful."); } printf("\nWaiting for client connection..."); //Wait for the client to connect BOOL bClientConnected = ConnectNamedPipe(hPipe, NULL); if (FALSE == bClientConnected) { printf("\nError occurred while connecting to the client: %d", GetLastError()); CloseHandle(hPipe); return 1; //Error } else { printf("\nConnectNamedPipe() was successful."); } char szBuffer[BUFFER_SIZE]; DWORD cbBytes; //We are connected to the client. //To communicate with the client we will use ReadFile()/WriteFile() //on the pipe handle - hPipe //Read client message BOOL bResult = ReadFile( hPipe, // handle to pipe szBuffer, // buffer to receive data sizeof(szBuffer), // size of buffer &cbBytes, // number of bytes read NULL); // not overlapped I/O if ( (!bResult) || (0 == cbBytes)) { printf("\nError occurred while reading from the client: %d", GetLastError()); CloseHandle(hPipe); return 1; //Error } else { printf("\nReadFile() was successful."); } printf("\nClient sent the following message: %s", szBuffer); strcpy(szBuffer, ACK_MESG_RECV); //Reply to client bResult = WriteFile( hPipe, // handle to pipe szBuffer, // buffer to write from strlen(szBuffer)+1, // number of bytes to write, include the NULL &cbBytes, // number of bytes written NULL); // not overlapped I/O if ( (!bResult) || (strlen(szBuffer)+1 != cbBytes)) { printf("\nError occurred while writing to the client: %d", GetLastError()); CloseHandle(hPipe); return 1; //Error } else { printf("\nWriteFile() was successful."); } CloseHandle(hPipe); return 0; //Success }
apr_status_t proc_spawn_process(const char *cmdline, fcgid_proc_info *procinfo, fcgid_procnode *procnode) { HANDLE *finish_event, listen_handle; SECURITY_ATTRIBUTES SecurityAttributes; fcgid_server_conf *sconf; apr_procattr_t *proc_attr; apr_status_t rv; apr_file_t *file; const char * const *proc_environ; char sock_path[FCGID_PATH_MAX]; const char **wargv; /* Build wrapper args */ apr_tokenize_to_argv(cmdline, (char ***)&wargv, procnode->proc_pool); memset(&SecurityAttributes, 0, sizeof(SecurityAttributes)); /* Prepare finish event */ finish_event = apr_palloc(procnode->proc_pool, sizeof(HANDLE)); *finish_event = CreateEvent(NULL, TRUE, FALSE, NULL); if (*finish_event == NULL || !SetHandleInformation(*finish_event, HANDLE_FLAG_INHERIT, TRUE)) { ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(), procinfo->main_server, "mod_fcgid: can't create mutex for subprocess"); return APR_ENOLOCK; } apr_pool_cleanup_register(procnode->proc_pool, finish_event, close_finish_event, apr_pool_cleanup_null); /* For proc_kill_gracefully() */ apr_pool_userdata_set(finish_event, FINISH_EVENT_DATA_NAME, NULL, procnode->proc_pool); /* Pass the finish event id to subprocess */ apr_table_setn(procinfo->proc_environ, SHUTDOWN_EVENT_NAME, apr_ltoa(procnode->proc_pool, (long) *finish_event)); /* Prepare the listen namedpipe file name (no check for truncation) */ apr_snprintf(sock_path, sizeof sock_path, "\\\\.\\pipe\\fcgidpipe-%lu.%d", GetCurrentProcessId(), g_process_counter++); /* Prepare the listen namedpipe handle */ SecurityAttributes.bInheritHandle = TRUE; SecurityAttributes.nLength = sizeof(SecurityAttributes); SecurityAttributes.lpSecurityDescriptor = NULL; listen_handle = CreateNamedPipe(sock_path, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 8192, 8192, 0, &SecurityAttributes); if (listen_handle == INVALID_HANDLE_VALUE) { ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(), procinfo->main_server, "mod_fcgid: can't create namedpipe for subprocess"); return APR_ENOSOCKET; } apr_cpystrn(procnode->socket_path, sock_path, sizeof(procnode->socket_path)); apr_cpystrn(procnode->executable_path, wargv[0], sizeof(procnode->executable_path)); /* Build environment variables */ proc_environ = (const char * const *) ap_create_environment(procnode->proc_pool, procinfo->proc_environ); if (!proc_environ) { ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(), procinfo->main_server, "mod_fcgid: can't build environment variables"); return APR_ENOMEM; } /* Create process now */ if ((rv = apr_procattr_create(&proc_attr, procnode->proc_pool)) != APR_SUCCESS || (rv = apr_procattr_dir_set(proc_attr, ap_make_dirstr_parent(procnode->proc_pool, wargv[0]))) != APR_SUCCESS || (rv = apr_procattr_cmdtype_set(proc_attr, APR_PROGRAM)) != APR_SUCCESS || (rv = apr_procattr_detach_set(proc_attr, 1)) != APR_SUCCESS || (rv = apr_procattr_io_set(proc_attr, APR_NO_PIPE, APR_NO_FILE, APR_NO_FILE)) != APR_SUCCESS || (rv = apr_os_file_put(&file, &listen_handle, 0, procnode->proc_pool)) != APR_SUCCESS || (rv = apr_procattr_child_in_set(proc_attr, file, NULL)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_WARNING, rv, procinfo->main_server, "mod_fcgid: can't create FastCGI process attribute"); CloseHandle(listen_handle); return APR_ENOPROC; } /* fork and exec now */ rv = apr_proc_create(&(procnode->proc_id), wargv[0], wargv, proc_environ, proc_attr, procnode->proc_pool); /* OK, I created the process, now put it back to idle list */ CloseHandle(listen_handle); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server, "mod_fcgid: can't run %s", wargv[0]); return rv; } /* FcgidWin32PreventOrphans feature */ sconf = ap_get_module_config(procinfo->main_server->module_config, &fcgid_module); if (sconf->hJobObjectForAutoCleanup != NULL) { /* Associate cgi process to current process */ if (AssignProcessToJobObject(sconf->hJobObjectForAutoCleanup, procnode->proc_id.hproc) == 0) { ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(), procinfo->main_server, "mod_fcgid: unable to assign child process to " "job object"); } } return APR_SUCCESS; }
Eina_Bool ecore_con_local_listen(Ecore_Con_Server *svr) { char buf[256]; HANDLE thread_listening; Ecore_Win32_Handler *handler; if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) { ERR("Your system does not support abstract sockets!"); return EINA_FALSE; } if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name); else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM) { const char *computername; computername = getenv("CoMPUTERNAME"); snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name); } svr->path = strdup(buf); if (!svr->path) { ERR("Allocation failed"); return EINA_FALSE; } /* * synchronuous * block mode * wait mode */ svr->pipe = CreateNamedPipe(svr->path, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE, 5000, NULL); if (svr->pipe == INVALID_HANDLE_VALUE) { ERR("Creation of the named pipe failed"); goto free_path; } /* * We use ConnectNamedPipe() to wait for a client to connect. * As the function is blocking, to let the main loop continuing * its iterations, we call ConnectNamedPipe() in a thread */ thread_listening = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_listening, svr, CREATE_SUSPENDED, NULL); if (!thread_listening) { ERR("Creation of the listening thread failed"); goto close_pipe; } handler = ecore_main_win32_handler_add(thread_listening, _ecore_con_local_win32_client_add, svr); if (!handler) { ERR("Creation of the client add handler failed"); goto del_handler; } svr->read_stopped = EINA_TRUE; ResumeThread(thread_listening); return EINA_TRUE; del_handler: ecore_main_win32_handler_del(handler); close_pipe: CloseHandle(svr->pipe); free_path: free(svr->path); svr->path = NULL; return EINA_FALSE; }
static int lang_pipe_run(RLang *lang, const char *code, int len) { #if __UNIX__ int safe_in = dup (0); int child, ret; int input[2]; int output[2]; pipe (input); pipe (output); env ("R2PIPE_IN", input[0]); env ("R2PIPE_OUT", output[1]); child = r_sys_fork (); if (child == -1) { /* error */ } else if (child == 0) { /* children */ r_sandbox_system (code, 1); write (input[1], "", 1); close (input[0]); close (input[1]); close (output[0]); close (output[1]); exit (0); return false; } else { /* parent */ char *res, buf[1024]; /* Close pipe ends not required in the parent */ close (output[1]); close (input[0]); r_cons_break (NULL, NULL); for (;;) { if (r_cons_singleton ()->breaked) { break; } memset (buf, 0, sizeof (buf)); ret = read (output[0], buf, sizeof (buf)-1); if (ret <1 || !buf[0]) { break; } buf[sizeof (buf)-1] = 0; res = lang->cmd_str ((RCore*)lang->user, buf); //eprintf ("%d %s\n", ret, buf); if (res) { write (input[1], res, strlen (res)+1); free (res); } else { eprintf ("r_lang_pipe: NULL reply for (%s)\n", buf); write (input[1], "", 1); // NULL byte } } /* workaround to avoid stdin closed */ if (safe_in != -1) close (safe_in); safe_in = open (ttyname(0), O_RDONLY); if (safe_in != -1) { dup2 (safe_in, 0); } else eprintf ("Cannot open ttyname(0) %s\n", ttyname(0)); r_cons_break_end (); } close (input[0]); close (input[1]); close (output[0]); close (output[1]); if (safe_in != -1) close (safe_in); waitpid (child, NULL, 0); return true; #else #if __WINDOWS__ HANDLE hThread = 0; char buf[512]; sprintf(buf,"R2PIPE_IN%x",_getpid()); SetEnvironmentVariable("R2PIPE_PATH",buf); sprintf(buf,"\\\\.\\pipe\\R2PIPE_IN%x",_getpid()); hPipeInOut = CreateNamedPipe(buf, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, PIPE_BUF_SIZE, PIPE_BUF_SIZE, 0, NULL); hproc = myCreateChildProcess (code); if (!hproc) { return false; } bStopThread=FALSE; hThread = CreateThread (NULL, 0,ThreadFunction,lang, 0,0); WaitForSingleObject (hproc, INFINITE ); bStopThread = TRUE; DeleteFile (buf); WaitForSingleObject (hThread, INFINITE); CloseHandle (hPipeInOut); return true; #endif #endif }
/**F*****************************************************************/ void cmd (spp_ctx *c) { SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; STARTUPINFO si; OVERLAPPED lap; HANDLE lh[4]; DWORD p, e, wr; spp_blk in, out; int r; char buf[MAX_PATH]; HANDLE evt[MAXIMUM_WAIT_OBJECTS]; DWORD evt_cnt=0, sck_evt=0, stdout_evt=0, proc_evt=0; DEBUG_PRINT ("create event for socket"); evt[sck_evt = evt_cnt++] = WSACreateEvent(); DEBUG_PRINT("create event for stdout handle of cmd.exe"); evt[stdout_evt = evt_cnt++] = CreateEvent (NULL, TRUE, TRUE, NULL); DEBUG_PRINT("initialize security descriptor"); sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; DEBUG_PRINT("create anonymous read/write pipes for stdin of cmd.exe"); if (CreatePipe (&lh[0], &lh[1], &sa, 0)) { DEBUG_PRINT("format named pipe using tick count and current process id"); wnsprintf (buf, MAX_PATH, "\\\\.\\pipe\\%08X", GetCurrentProcessId() ^ GetTickCount()); DEBUG_PRINT("create named pipe for stdout/stderr of cmd.exe"); lh[2] = CreateNamedPipe (buf, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, 0, NULL); if (lh[2] != INVALID_HANDLE_VALUE) { DEBUG_PRINT("open the named pipe"); lh[3] = CreateFile (buf, MAXIMUM_ALLOWED, 0, &sa, OPEN_EXISTING, 0, NULL); if (lh[3] != INVALID_HANDLE_VALUE) { // zero initialize parameters for CreateProcess ZeroMemory (&si, sizeof (si)); ZeroMemory (&pi, sizeof (pi)); si.cb = sizeof (si); si.hStdInput = lh[0]; // assign the anon read pipe si.hStdError = lh[3]; // assign the named write pipe si.hStdOutput = lh[3]; // si.dwFlags = STARTF_USESTDHANDLES; DEBUG_PRINT("execute cmd.exe with no window"); if (CreateProcess (NULL, "cmd", NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { // monitor state of cmd.exe evt[proc_evt = evt_cnt++] = pi.hProcess; ZeroMemory (&lap, sizeof (lap)); // assign stdout event lap.hEvent = evt[stdout_evt]; // set pending to 0 p=0; for (;;) { DEBUG_PRINT("wait for events on cmd.exe and socket"); e=wait_evt(evt, evt_cnt, sck_evt, c->s); // cmd.exe ended? if (e==proc_evt) { DEBUG_PRINT("cmd.exe ended"); break; } // wait failed? if (e == -1) { DEBUG_PRINT("wait failed"); break; } // is this socket event? if (e == sck_evt) { DEBUG_PRINT("socket event"); // receive data from socket r=spp_recv (c, &in); if (r!=SPP_ERR_OK) { DEBUG_PRINT("spp_recv error"); break; } // write to stdin of cmd.exe using anonymous write pipe WriteFile (lh[1], in.buf, in.len, &wr, 0); } else // output from cmd.exe? if (e == stdout_evt) { // if not in pending read state, read from named pipe if (p == 0) { ReadFile (lh[2], out.buf, SPP_DATA_LEN, (LPDWORD)&out.len, &lap); p++; } else { // get overlapped result if (!GetOverlappedResult (lh[2], &lap, (LPDWORD)&out.len, FALSE)) { break; } } // if we have something if (out.len != 0) { // send to remote r=spp_send (c, &out); if (r!=SPP_ERR_OK) { DEBUG_PRINT("spp_send error %i", r); break; } WSAEventSelect(c->s, evt[sck_evt], FD_CLOSE | FD_READ); p--; } } } // end cmd.exe incase it's still running TerminateProcess (pi.hProcess, 0); // close handles and decrease events CloseHandle (pi.hThread); CloseHandle (pi.hProcess); evt_cnt--; } // close handle to named pipe for stdout CloseHandle (lh[3]); } // close named pipe for stdout CloseHandle (lh[2]); } // close anon pipes for read/write to stdin CloseHandle (lh[1]); CloseHandle (lh[0]); } // close stdout event handle CloseHandle (evt[stdout_evt]); evt_cnt--; // close socket event handle CloseHandle (evt[sck_evt]); evt_cnt--; // tell server, we're exiting DEBUG_PRINT("sending termination signal"); out.len=0; spp_send(c, &out); }
DWORD namedPipeStuff() { DWORD dwError = ERROR_SUCCESS; PSECURITY_ATTRIBUTES pSa = NULL; HANDLE hNamedPipe = INVALID_HANDLE_VALUE; // Prepare the security attributes (the lpSecurityAttributes parameter in // CreateNamedPipe) for the pipe. This is optional. If the // lpSecurityAttributes parameter of CreateNamedPipe is NULL, the named // pipe gets a default security descriptor and the handle cannot be // inherited. The ACLs in the default security descriptor of a pipe grant // full control to the LocalSystem account, (elevated) administrators, // and the creator owner. They also give only read access to members of // the Everyone group and the anonymous account. However, if you want to // customize the security permission of the pipe, (e.g. to allow // Authenticated Users to read from and write to the pipe), you need to // create a SECURITY_ATTRIBUTES structure. if (!CreatePipeSecurity(&pSa)) { dwError = GetLastError(); wprintf(L"CreatePipeSecurity failed w/err 0x%08lx\n", dwError); goto Cleanup; } // Create the named pipe. hNamedPipe = CreateNamedPipe( FULL_PIPE_NAME, // Pipe name. PIPE_ACCESS_DUPLEX, // The server and client processes can // read from and write to the pipe PIPE_TYPE_MESSAGE | // Message type pipe PIPE_READMODE_MESSAGE | // Message-read mode PIPE_WAIT, // Blocking mode is enabled PIPE_UNLIMITED_INSTANCES, // Max. instances BUFFER_SIZE, // Output buffer size in bytes BUFFER_SIZE, // Input buffer size in bytes NMPWAIT_USE_DEFAULT_WAIT, // Time-out interval pSa // Security attributes ); if (hNamedPipe == INVALID_HANDLE_VALUE) { dwError = GetLastError(); wprintf(L"Unable to create named pipe w/err 0x%08lx\n", dwError); goto Cleanup; } wprintf(L"The named pipe (%s) is created.\n", FULL_PIPE_NAME); // Wait for the client to connect. wprintf(L"Waiting for the client's connection...\n"); if (!ConnectNamedPipe(hNamedPipe, NULL)) { if (ERROR_PIPE_CONNECTED != GetLastError()) { dwError = GetLastError(); wprintf(L"ConnectNamedPipe failed w/err 0x%08lx\n", dwError); goto Cleanup; } } wprintf(L"Client is connected.\n"); // // Receive a request from client. // BOOL fFinishRead = FALSE; do { wchar_t chRequest[BUFFER_SIZE]; DWORD cbRequest, cbRead; cbRequest = sizeof(chRequest); fFinishRead = ReadFile( hNamedPipe, // Handle of the pipe chRequest, // Buffer to receive data cbRequest, // Size of buffer in bytes &cbRead, // Number of bytes read NULL // Not overlapped I/O ); if (!fFinishRead && ERROR_MORE_DATA != GetLastError()) { dwError = GetLastError(); wprintf(L"ReadFile from pipe failed w/err 0x%08lx\n", dwError); goto Cleanup; } wprintf(L"Receive %ld bytes from client: \"%s\"\n", cbRead, chRequest); } while (!fFinishRead); // Repeat loop if ERROR_MORE_DATA // // Send a response from server to client. // wchar_t chResponse[] = RESPONSE_MESSAGE; DWORD cbResponse, cbWritten; cbResponse = sizeof(chResponse); if (!WriteFile( hNamedPipe, // Handle of the pipe chResponse, // Buffer to write cbResponse, // Number of bytes to write &cbWritten, // Number of bytes written NULL // Not overlapped I/O )) { dwError = GetLastError(); wprintf(L"WriteFile to pipe failed w/err 0x%08lx\n", dwError); goto Cleanup; } wprintf(L"Send %ld bytes to client: \"%s\"\n", cbWritten, chResponse); // Flush the pipe to allow the client to read the pipe's contents // before disconnecting. Then disconnect the client's connection. FlushFileBuffers(hNamedPipe); DisconnectNamedPipe(hNamedPipe); Cleanup: // Centralized cleanup for all allocated resources. if (pSa != NULL) { FreePipeSecurity(pSa); pSa = NULL; } if (hNamedPipe != INVALID_HANDLE_VALUE) { CloseHandle(hNamedPipe); hNamedPipe = INVALID_HANDLE_VALUE; } return dwError; }
DWORD WINAPI server_loop(LPVOID lpParameter) { BOOL res; SvcDebugOut("server_loop: alive\n", 0); if (!CreatePipesSA()) { SvcDebugOut("CreatePipesSA failed (%08X)\n", GetLastError()); return -1; } SvcDebugOut("server_loop: CreatePipesSA done\n", 0); for (;;) { SvcDebugOut("server_loop: Create Pipe\n", 0); OV_HANDLE *pipe; pipe = (OV_HANDLE *)malloc(sizeof(OV_HANDLE)); ZeroMemory(&pipe->o, sizeof(OVERLAPPED)); pipe->o.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); pipe->h = CreateNamedPipe("\\\\.\\pipe\\" PIPE_NAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE, NMPWAIT_USE_DEFAULT_WAIT, &sa); if (pipe->h == INVALID_HANDLE_VALUE) { SvcDebugOut("CreatePipe failed(%08X)\n", GetLastError()); CloseHandle(pipe->o.hEvent); free(pipe); return 0; } SvcDebugOut("server_loop: Connect Pipe\n", 0); if (ConnectNamedPipe(pipe->h, &pipe->o)) { SvcDebugOut("server_loop: Connect Pipe err %08X\n", GetLastError()); res = FALSE; } else { switch (GetLastError()) { case ERROR_IO_PENDING: SvcDebugOut("server_loop: Connect Pipe(0) pending\n", 0); DWORD t; res = GetOverlappedResult(pipe->h, &pipe->o, &t, TRUE); break; case ERROR_PIPE_CONNECTED: SvcDebugOut("server_loop: Connect Pipe(0) connected\n", 0); res = TRUE; break; default: SvcDebugOut("server_loop: Connect Pipe(0) err %08X\n", GetLastError()); res = FALSE; } } if (res) { connection_data *cd = malloc(sizeof(connection_data)); cd->pipe = pipe; cd->conn_number = ++conn_number; SvcDebugOut("server_loop: CreateThread\n", 0); HANDLE th = CreateThread(NULL, /* no security attribute */ 0, /* default stack size */ (LPTHREAD_START_ROUTINE) handle_connection, (LPVOID) cd, /* thread parameter */ 0, /* not suspended */ NULL); /* returns thread ID */ if (!th) { SvcDebugOut("Cannot create thread\n", 0); CloseHandle(pipe->h); CloseHandle(pipe->o.hEvent); free(pipe); } else { CloseHandle(th); SvcDebugOut("server_loop: Thread created\n", 0); } } else { SvcDebugOut("server_loop: Pipe not connected\n", 0); CloseHandle(pipe->h); CloseHandle(pipe->o.hEvent); free(pipe); } } SvcDebugOut("server_loop: STH wrong\n", 0); }
int main(int argc, char* argv[]) { size_t ztNameLen = 0; char szPipeName[256] = ""; char szLogFileName[256] = ""; GetModuleFileNameEx(GetCurrentProcess(), NULL, szLogFileName, sizeof(szLogFileName)); ztNameLen = strlen(szLogFileName); szLogFileName[ztNameLen-3] = 'i'; szLogFileName[ztNameLen-2] = 'n'; szLogFileName[ztNameLen-1] = 'i'; GetPrivateProfileString("NamedPipe", "OutputWnd", "ERROR", szPipeName, sizeof(szPipeName), szLogFileName); if (strcmp(szPipeName, "ERROR") == 0) { char szInput[128] = ""; printf("Config file error!"); scanf("%s", szInput); return 1; } HANDLE hPipe = CreateNamedPipe( szPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE, 5000, NULL); if (hPipe == INVALID_HANDLE_VALUE) { char szInput[128] = ""; printf("Create pipe failed! Last error is %u", GetLastError()); scanf("%s", szInput); return 1; } printf("Wait connect...\n"); BOOL bConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); if (bConnected) { printf("Pipe connected\n"); while (TRUE) { DWORD dwReadSize = 0; char szBuf[BUFSIZE] = ""; BOOL bSuccess = ReadFile(hPipe, szBuf, BUFSIZE, &dwReadSize, NULL); if (bSuccess == FALSE || dwReadSize == 0) { printf("Pipe disconnect!\n"); break; } if (stricmp(szBuf, "exit") == 0) break; printf(szBuf); } } FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); return 0; }
int cmd_run(connection_context *c) { char buf[256]; int res = 0; int wres; char *cmdline; DWORD pipe_nr; cmdline = strchr(c->cmd, ' '); if (!cmdline) { goto finish; } ++cmdline; if (!get_token(c)) return 0; pipe_nr = (GetCurrentProcessId() << 16) + (DWORD) c->conn_number; sprintf(buf, "\\\\.\\pipe\\" PIPE_NAME_IN, pipe_nr); c->pin = CreateNamedPipe(buf, PIPE_ACCESS_DUPLEX, PIPE_WAIT, 1, BUFSIZE, BUFSIZE, NMPWAIT_USE_DEFAULT_WAIT, &sa); if (c->pin == INVALID_HANDLE_VALUE) { hprintf(c->pipe, "error Cannot create in pipe(%s), error 0x%08X\n", buf, GetLastError()); goto finishCloseToken; } sprintf(buf, "\\\\.\\pipe\\" PIPE_NAME_OUT, pipe_nr); c->pout = CreateNamedPipe(buf, PIPE_ACCESS_DUPLEX, PIPE_WAIT, 1, BUFSIZE, BUFSIZE, NMPWAIT_USE_DEFAULT_WAIT, &sa); if (c->pout == INVALID_HANDLE_VALUE) { hprintf(c->pipe, "error Cannot create out pipe(%s), error 0x%08X\n", buf, GetLastError()); goto finishClosePin; } sprintf(buf, "\\\\.\\pipe\\" PIPE_NAME_ERR, pipe_nr); c->perr = CreateNamedPipe(buf, PIPE_ACCESS_DUPLEX, PIPE_WAIT, 1, BUFSIZE, BUFSIZE, NMPWAIT_USE_DEFAULT_WAIT, &sa); if (c->perr == INVALID_HANDLE_VALUE) { hprintf(c->pipe, "error Cannot create err pipe(%s), error 0x%08x\n", buf, GetLastError()); goto finishClosePout; } /* Send handle to client (it will use it to connect pipes) */ hprintf(c->pipe, CMD_STD_IO_ERR " %08X\n", pipe_nr); wres = ConnectNamedPipe(c->pin, NULL); if (!wres) wres = (GetLastError() == ERROR_PIPE_CONNECTED); if (!wres) { hprintf(c->pipe, "error ConnectNamedPipe(pin)\n"); goto finishClosePerr; } wres = ConnectNamedPipe(c->pout, NULL); if (!wres) wres = (GetLastError() == ERROR_PIPE_CONNECTED); if (!wres) { hprintf(c->pipe, "error ConnectNamedPipe(pout)\n"); goto finishDisconnectPin; } wres = ConnectNamedPipe(c->perr, NULL); if (!wres) wres = (GetLastError() == ERROR_PIPE_CONNECTED); if (!wres) { hprintf(c->pipe, "error ConnectNamedPipe(perr)\n"); goto finishDisconnectPout; } SetHandleInformation(c->pin, HANDLE_FLAG_INHERIT, 1); SetHandleInformation(c->pout, HANDLE_FLAG_INHERIT, 1); SetHandleInformation(c->perr, HANDLE_FLAG_INHERIT, 1); SECURITY_ATTRIBUTES sattr; sattr.nLength = sizeof(SECURITY_ATTRIBUTES); sattr.bInheritHandle = TRUE; sattr.lpSecurityDescriptor = NULL; PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); STARTUPINFO si; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.hStdInput = c->pin; si.hStdOutput = c->pout; si.hStdError = c->perr; si.dwFlags |= STARTF_USESTDHANDLES; if (CreateProcessAsUser( c->token, NULL, cmdline, /* command line */ NULL, /* process security attributes */ NULL, /* primary thread security attributes */ TRUE, /* handles are inherited */ 0, /* creation flags */ NULL, /* use parent's environment */ NULL, /* use parent's current directory */ &si, /* STARTUPINFO pointer */ &pi)) /* receives PROCESS_INFORMATION */ { HANDLE hlist[2] = {c->pipe->o.hEvent, pi.hProcess}; DWORD ec; char str[1]; if (!ResetEvent(c->pipe->o.hEvent)) SvcDebugOut("ResetEvent error - %d\n", GetLastError()); if (!ReadFile(c->pipe->h, str, 1, NULL, &c->pipe->o) && GetLastError() != ERROR_IO_PENDING) SvcDebugOut("ReadFile(control_pipe) error - %d\n", GetLastError()); ec = WaitForMultipleObjects(2, hlist, FALSE, INFINITE); SvcDebugOut("WaitForMultipleObjects=%d\n", ec - WAIT_OBJECT_0); if (ec != WAIT_OBJECT_0) GetExitCodeProcess(pi.hProcess, &ec); else TerminateProcess(pi.hProcess, ec = 0x1234); FlushFileBuffers(c->pout); FlushFileBuffers(c->perr); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); hprintf(c->pipe, CMD_RETURN_CODE " %08X\n", ec); } else { hprintf(c->pipe, "error Creating process(%s) %d\n", cmdline, GetLastError()); } DisconnectNamedPipe(c->perr); finishDisconnectPout: DisconnectNamedPipe(c->pout); finishDisconnectPin: DisconnectNamedPipe(c->pin); finishClosePerr: CloseHandle(c->perr); finishClosePout: CloseHandle(c->pout); finishClosePin: CloseHandle(c->pin); finishCloseToken: CloseHandle(c->token); finish: return res; }
/// Creates the underlying O/S file handle. /// /// @param[in] pszName name of the pipe /// @param[in] bServer true if this is a server end, false if it is a client /// @param[in] bExclusive false if this is a pipe that can be shared by multiple clients or servers /// @param[in] bReader true if this is the reading end of a pipe, false if it is the writing end /// @return the O/S file handle static CTimeoutIO::FILE_REFERENCE _CreatePipe (const TCHAR *pszName, bool bServer, bool bExclusive, bool bReader) { #ifdef _WIN32 HANDLE handle; if (bServer) { SECURITY_DESCRIPTOR sd; SECURITY_ATTRIBUTES sa; InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION); // TODO [PLAT-1119] Get a SDDL from the registry for the DACL (and pass it into this library) SetSecurityDescriptorDacl (&sd, TRUE, NULL, FALSE); ZeroMemory (&sa, sizeof (sa)); sa.nLength = sizeof (sa); sa.lpSecurityDescriptor = &sd; sa.bInheritHandle = FALSE; handle = CreateNamedPipe ( pszName, (bReader ? PIPE_ACCESS_INBOUND : PIPE_ACCESS_OUTBOUND) | (bExclusive ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0) | FILE_FLAG_OVERLAPPED, (bExclusive ? PIPE_TYPE_BYTE | PIPE_READMODE_BYTE : PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE) | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, bExclusive ? 1 : PIPE_UNLIMITED_INSTANCES, 0, 0, 0, &sa); } else { // TODO: share or exclusive? We want a 1:1 on the pipe we've connected to - the server will open another for new clients handle = CreateFile (pszName, bReader ? GENERIC_READ : GENERIC_WRITE, 0/* bReader ? FILE_SHARE_READ : FILE_SHARE_WRITE */, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); } if (handle == INVALID_HANDLE_VALUE) { DWORD dwError = GetLastError (); LOGWARN (TEXT ("Couldn't create pipe ") << pszName << TEXT(", error ") << dwError); SetLastError (dwError); return NULL; } LOGINFO (TEXT ("Created pipe ") << pszName); return handle; #else /* ifdef _WIN32 */ if (bExclusive) { if (mkfifo (pszName, 0666)) { int ec = GetLastError (); LOGWARN (TEXT ("Couldn't create pipe ") << pszName << TEXT (", error ") << ec); SetLastError (ec); return 0; } CThread *poOpener = new CNamedPipeOpenThread (pszName, bReader ? O_WRONLY : O_RDONLY); poOpener->Start (); CThread::Release (poOpener); int file = open (pszName, bReader ? O_RDONLY : O_WRONLY); if (file <= 0) { int ec = GetLastError (); LOGWARN (TEXT ("Couldn't open pipe ") << pszName << TEXT (", error ") << ec); if (unlink (pszName)) { LOGWARN (TEXT ("Couldn't delete pipe ") << pszName << TEXT (", error ") << GetLastError ()); } SetLastError (ec); return 0; } LOGINFO (TEXT ("Created pipe ") << pszName); return file; } else { int sock; sock = socket (AF_UNIX, SOCK_STREAM, 0); if (sock < 0) { int ec = GetLastError (); LOGWARN (TEXT ("Couldn't open pipe ") << pszName << TEXT (", error ") << ec); SetLastError (ec); return 0; } if (!_SetDefaultSocketOptions (sock)) { int ec = GetLastError (); close (sock); LOGWARN (TEXT ("Couldn't set default options ") << pszName << TEXT (", error ") << ec); SetLastError (ec); return 0; } struct sockaddr_un addr; addr.sun_family = AF_UNIX; StringCbPrintf (addr.sun_path, sizeof (addr.sun_path), TEXT ("%s"), pszName); if (bServer) { if (!unlink (pszName)) { LOGINFO (TEXT ("Deleted previous instance of ") << pszName); } if (bind (sock, (struct sockaddr*)&addr, sizeof (addr.sun_family) + _tcslen (addr.sun_path))) { int ec = GetLastError (); close (sock); LOGWARN (TEXT ("Couldn't open pipe ") << pszName << TEXT (", error ") << ec); SetLastError (ec); return 0; } if (fcntl (sock, F_SETFL, O_NONBLOCK) || listen (sock, 0)) { int ec = GetLastError (); close (sock); LOGWARN (TEXT ("Couldn't open pipe ") << pszName << TEXT (", error ") << ec); SetLastError (ec); return 0; } LOGINFO (TEXT ("Created server Unix Domain Socket ") << pszName); } else { if (connect (sock, (struct sockaddr*)&addr, sizeof (addr.sun_family) + _tcslen (addr.sun_path))) { int ec = GetLastError (); close (sock); LOGWARN (TEXT ("Couldn't open pipe ") << pszName << TEXT (", error ") << ec); switch (ec) { case EAGAIN : LOGDEBUG (TEXT ("Translating EAGAIN to ENOENT")); ec = ENOENT; break; case ECONNREFUSED : LOGDEBUG (TEXT ("Translating ECONNREFUSED to ENOENT")); ec = ENOENT; break; } SetLastError (ec); return 0; } LOGDEBUG (TEXT ("Connection accepted, waiting for handshake confirmation")); if ((recv (sock, addr.sun_path, 1, 0) != 1) || fcntl (sock, F_SETFL, O_NONBLOCK)) { int ec = GetLastError (); close (sock); LOGWARN (TEXT ("Handshake not received on ") << pszName << TEXT (", error ") << ec); switch (ec) { case EAGAIN : LOGDEBUG (TEXT ("Translating EAGAIN to ENOENT")); ec = ENOENT; break; } SetLastError (ec); return 0; } LOGINFO (TEXT ("Connected to Unix Domain Socket ") << pszName); } return sock; } #endif /* ifdef _WIN32 */ }
static int makeChannel(MprCmd *cmd, int index) { SECURITY_ATTRIBUTES clientAtt, serverAtt, *att; HANDLE readHandle, writeHandle; MprCmdFile *file; MprTime now; char *pipeBuf; int openMode, pipeMode, readFd, writeFd; static int tempSeed = 0; memset(&clientAtt, 0, sizeof(clientAtt)); clientAtt.nLength = sizeof(SECURITY_ATTRIBUTES); clientAtt.bInheritHandle = 1; /* * Server fds are not inherited by the child */ memset(&serverAtt, 0, sizeof(serverAtt)); serverAtt.nLength = sizeof(SECURITY_ATTRIBUTES); serverAtt.bInheritHandle = 0; file = &cmd->files[index]; now = ((int) mprGetTime(cmd) & 0xFFFF) % 64000; pipeBuf = mprAsprintf(cmd, -1, "\\\\.\\pipe\\MPR_%d_%d_%d.tmp", getpid(), (int) now, ++tempSeed); /* * Pipes are always inbound. The file below is outbound. we swap whether the client or server * inherits the pipe or file. MPR_CMD_STDIN is the clients input pipe. * Pipes are blocking since both ends share the same blocking mode. Client must be blocking. */ openMode = PIPE_ACCESS_INBOUND; pipeMode = 0; att = (index == MPR_CMD_STDIN) ? &clientAtt : &serverAtt; readHandle = CreateNamedPipe(pipeBuf, openMode, pipeMode, 1, 0, 256 * 1024, 1, att); if (readHandle == INVALID_HANDLE_VALUE) { mprError(cmd, "Can't create stdio pipes %s. Err %d\n", pipeBuf, mprGetOsError()); return MPR_ERR_CANT_CREATE; } readFd = (int) (int64) _open_osfhandle((long) readHandle, 0); att = (index == MPR_CMD_STDIN) ? &serverAtt: &clientAtt; writeHandle = CreateFile(pipeBuf, GENERIC_WRITE, 0, att, OPEN_EXISTING, openMode, 0); writeFd = (int) _open_osfhandle((long) writeHandle, 0); if (readFd < 0 || writeFd < 0) { mprError(cmd, "Can't create stdio pipes %s. Err %d\n", pipeBuf, mprGetOsError()); return MPR_ERR_CANT_CREATE; } if (index == MPR_CMD_STDIN) { file->clientFd = readFd; file->fd = writeFd; file->handle = writeHandle; } else { file->clientFd = writeFd; file->fd = readFd; file->handle = readHandle; } mprFree(pipeBuf); return 0; }
bool CMPVlcSourceStream::Load(const TCHAR* fn) { char def_options[512]; char def_sout[512]; LogDebug("Load()"); Clear(); strncpy(m_fn, fn, sizeof(m_fn)); sprintf(m_pipename, "\\\\.\\pipe\\vlc2ds_%d_%d", GetCurrentThreadId(), GetTickCount()); LogDebug("Creating named pipe %s", m_pipename); m_hPipe = CreateNamedPipe( m_pipename, // pipe name PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access PIPE_TYPE_MESSAGE | // message type pipe PIPE_READMODE_BYTE | // message-read mode PIPE_WAIT, // blocking mode PIPE_UNLIMITED_INSTANCES, // max. instances IPTV_BUFFER_SIZE, // output buffer size IPTV_BUFFER_SIZE, // input buffer size 0, // client time-out NULL); // default security attribute if (!m_hPipe) { LogError("CreateNamedPipe failed"); return false; } /* Load the VLC engine */ m_vlc = libvlc_new (0, NULL); if (!m_vlc) { LogError("libvlc_new failed"); return false; } // parse input MRL and options GetPrivateProfileString("main", "options", "", def_options, sizeof(def_options), m_inifile); GetPrivateProfileString("main", "sout", "file{mux=ts,dst=\"\\%s\"}", def_sout, sizeof(def_sout), m_inifile); if (strlen(def_options) > 0) { strcat_s(m_fn, " "); strcat_s(m_fn, def_options); } LogInfo("Adding media: %s", m_fn); int argc; m_argv = CommandLineToArgvA(m_fn, &argc); m_options = (char**)CoTaskMemAlloc(argc * sizeof(char*)); int nopt = 0; int noremux = -1; char *opt_out = 0; for (int n = 0; n < argc; n++) { if (m_argv[n][0] == '-' && m_argv[n][1] == '-') m_options[nopt] = m_argv[n] + 2; else if (m_argv[n][0] == ':') m_options[nopt] = m_argv[n] + 1; else { strncpy(m_input, m_argv[n], sizeof(m_input)); continue; } if (strncmp(m_options[nopt], "sout", 4) == 0) // disable direct ts dump if there are any sout options noremux = 0; if (strncmp(m_options[nopt], "sout=", 5) == 0) opt_out = m_options[nopt] + 5; else if (strncmp(m_options[nopt], "exec=", 5) == 0) m_exec = m_options[nopt] + 5; else if (strncmp(m_options[nopt], "exec-opt=", 9) == 0) m_exec_opt = m_options[nopt] + 9; else if (strncmp(m_options[nopt], "exec-wait=", 10) == 0) m_exec_wait = atoi(m_options[nopt] + 10); else if (strncmp(m_options[nopt], "no-remux", 8) == 0 && noremux == -1) noremux = 1; else nopt++; } char t_output[512]; if (noremux == 1) { sprintf_s(m_dump_opt, "ts-dump-file=%s", m_pipename); m_options[nopt++] = m_dump_opt; strcpy_s(m_output, "#dummy"); } else { sprintf_s(t_output, def_sout, m_pipename); if (opt_out) sprintf_s(m_output, "%s:%s", opt_out, t_output); else sprintf_s(m_output, "#%s", t_output); } LogDebug("input=%s", m_input); LogDebug("output=%s", m_output); for (int i = 0; i < nopt; i++) LogDebug("options[%d]=%s", i, m_options[i]); if (libvlc_vlm_add_broadcast(m_vlc, "vlc_ds_stream", m_input, m_output, nopt, m_options, true, 0) != 0) { LogError("libvlc_vlm_add_broadcast failed"); return false; } return true; }
VOID WINAPI ServiceStart(const wchar_t * config_file) { PSID pEveryoneSID = NULL; PACL pACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; EXPLICIT_ACCESS ea[1]; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = {SECURITY_WORLD_SID_AUTHORITY}; SECURITY_ATTRIBUTES sa; if(!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID)) { goto cleanup; } ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea[0].grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL; ea[0].grfAccessMode = SET_ACCESS; ea[0].grfInheritance= NO_INHERITANCE; ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID; if (SetEntriesInAcl(1, ea, NULL, &pACL)) { goto cleanup; } pSD = (PSECURITY_DESCRIPTOR) malloc(SECURITY_DESCRIPTOR_MIN_LENGTH); if(!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { goto cleanup; } if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) { goto cleanup; } sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = pSD; sa.bInheritHandle = FALSE; hPipe = CreateNamedPipe(PIPE_NAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 0, sizeof(mount_params), 0, &sa); mount_params params; ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0); while (!bStop) { DWORD read = 0, total; if (hPipe != INVALID_HANDLE_VALUE) { debug(D_NOTICE, "Service main - Connecting pipe..."); if (!ConnectNamedPipe(hPipe, NULL)) { Sleep(500); debug(D_ERROR, "Service main - failed to connect pipe %lu ...", GetLastError()); continue; } debug(D_NOTICE, "Service main - Connected pipe..."); } else { debug(D_ERROR, "Service main - Braking because of broken pipe."); break; } debug(D_NOTICE, "Service main - received command"); if (ReadFile(hPipe, ¶ms, sizeof(mount_params), &read, NULL)) { total = read; while (read && total < sizeof(mount_params)) { if (!ReadFile(hPipe, ((char*)¶ms+total), sizeof(mount_params)-total, &read, NULL)) { read = 0; debug(D_ERROR, "Service main - error inner read data from pipe"); } total += read; } if (total == sizeof(mount_params)) { if ((params.options & OPT_MASK_COMMAND) == OPT_COMMAND_MOUNT) { debug(D_NOTICE, "Service main - mounting, %s", params.auth); mount(¶ms); Sleep(200); // wait thread to start } else { debug(D_NOTICE, "Service main - unmounting"); DisconnectNamedPipe(hPipe); unmount(); } } } else { debug(D_ERROR, "Service main - error read data from pipe"); } DisconnectNamedPipe(hPipe); } cleanup: if (pEveryoneSID) FreeSid(pEveryoneSID); if (pACL) free(pACL); if (pSD) free(pSD); ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0); disconnect_pipe(); unmount(); ReportStatusToSCMgr(SERVICE_STOPPED, NO_ERROR, 0); storeKey(KEY_DELETE, ""); debug(D_NOTICE, "Service main - exit"); }
bool SharedPortEndpoint::CreateListener() { #ifndef HAVE_SHARED_PORT return false; #elif WIN32 if( m_listening ) { dprintf(D_ALWAYS, "SharedPortEndpoint: listener already created.\n"); return true; } m_full_name.formatstr("%s%c%s", m_socket_dir.c_str(), DIR_DELIM_CHAR, m_local_id.c_str()); pipe_end = CreateNamedPipe( m_full_name.Value(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 1024, 1024, 0, NULL); if(pipe_end == INVALID_HANDLE_VALUE) { DWORD error = GetLastError(); EXCEPT("SharedPortEndpoint: Failed to create named pipe: %d", error); } #elif HAVE_SCM_RIGHTS_PASSFD if( m_listening ) { return true; } int sock_fd = socket(AF_UNIX,SOCK_STREAM,0); if( sock_fd == -1 ) { dprintf(D_ALWAYS, "ERROR: SharedPortEndpoint: failed to open listener socket: %s\n", strerror(errno)); return false; } m_listener_sock.close(); m_listener_sock.assignDomainSocket( sock_fd ); m_full_name.formatstr("%s%c%s", m_socket_dir.c_str(), DIR_DELIM_CHAR, m_local_id.c_str()); struct sockaddr_un named_sock_addr; memset(&named_sock_addr, 0, sizeof(named_sock_addr)); named_sock_addr.sun_family = AF_UNIX; unsigned named_sock_addr_len; bool is_no_good; if (m_is_file_socket) { strncpy(named_sock_addr.sun_path, m_full_name.Value(), sizeof(named_sock_addr.sun_path)-1); named_sock_addr_len = SUN_LEN(&named_sock_addr); is_no_good = strcmp(named_sock_addr.sun_path,m_full_name.Value()); } else { strncpy(named_sock_addr.sun_path+1, m_full_name.Value(), sizeof(named_sock_addr.sun_path)-2); named_sock_addr_len = sizeof(named_sock_addr) - sizeof(named_sock_addr.sun_path) + 1 + strlen(named_sock_addr.sun_path+1); is_no_good = strcmp(named_sock_addr.sun_path+1,m_full_name.Value());; } if( is_no_good ) { dprintf(D_ALWAYS, "ERROR: SharedPortEndpoint: full listener socket name is too long." " Consider changing DAEMON_SOCKET_DIR to avoid this:" " %s\n",m_full_name.Value()); return false; } while( true ) { priv_state orig_priv = get_priv(); bool tried_priv_switch = false; if( orig_priv == PRIV_USER ) { set_condor_priv(); tried_priv_switch = true; } int bind_rc = bind( sock_fd, (struct sockaddr *)&named_sock_addr, named_sock_addr_len); if( tried_priv_switch ) { set_priv( orig_priv ); } if( bind_rc == 0 ) { break; } int bind_errno = errno; // bind failed: deal with some common sources of error if( m_is_file_socket && RemoveSocket(m_full_name.Value()) ) { dprintf(D_ALWAYS, "WARNING: SharedPortEndpoint: removing pre-existing socket %s\n", m_full_name.Value()); continue; } else if( m_is_file_socket && MakeDaemonSocketDir() ) { dprintf(D_ALWAYS, "SharedPortEndpoint: creating DAEMON_SOCKET_DIR=%s\n", m_socket_dir.Value()); continue; } dprintf(D_ALWAYS, "ERROR: SharedPortEndpoint: failed to bind to %s: %s\n", m_full_name.Value(), strerror(bind_errno)); return false; } if( listen( sock_fd, param_integer( "SOCKET_LISTEN_BACKLOG", 500 ) ) ) { dprintf(D_ALWAYS, "ERROR: SharedPortEndpoint: failed to listen on %s: %s\n", m_full_name.Value(), strerror(errno)); return false; } m_listener_sock._state = Sock::sock_special; m_listener_sock._special_state = ReliSock::relisock_listen; #else #error HAVE_SHARED_PORT is defined, but no method for passing fds is enabled. #endif m_listening = true; return true; }
int OS_CreateLocalIpcFd(const char *bindPath, int backlog) { int pseudoFd = -1; short port = getPort(bindPath); if (acceptMutex == INVALID_HANDLE_VALUE) { acceptMutex = CreateMutex(NULL, FALSE, NULL); if (acceptMutex == NULL) return -2; if (! SetHandleInformation(acceptMutex, HANDLE_FLAG_INHERIT, TRUE)) return -3; } // There's nothing to be gained (at the moment) by a shutdown Event if (port && *bindPath != ':' && strncmp(bindPath, LOCALHOST, strlen(LOCALHOST))) { fprintf(stderr, "To start a service on a TCP port can not " "specify a host name.\n" "You should either use \"localhost:<port>\" or " " just use \":<port>.\"\n"); exit(1); } listenType = (port) ? FD_SOCKET_SYNC : FD_PIPE_ASYNC; if (port) { SOCKET listenSock; struct sockaddr_in sockAddr; int sockLen = sizeof(sockAddr); memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sin_family = AF_INET; sockAddr.sin_addr.s_addr = htonl(INADDR_ANY); sockAddr.sin_port = htons(port); listenSock = socket(AF_INET, SOCK_STREAM, 0); if (listenSock == INVALID_SOCKET) { return -4; } if (bind(listenSock, (struct sockaddr *) &sockAddr, sockLen) ) { return -12; } if (listen(listenSock, backlog)) { return -5; } pseudoFd = Win32NewDescriptor(listenType, listenSock, -1); if (pseudoFd == -1) { closesocket(listenSock); return -6; } hListen = (HANDLE) listenSock; } else { HANDLE hListenPipe = INVALID_HANDLE_VALUE; char *pipePath = malloc(strlen(bindPathPrefix) + strlen(bindPath) + 1); if (! pipePath) { return -7; } strcpy(pipePath, bindPathPrefix); strcat(pipePath, bindPath); hListenPipe = CreateNamedPipe(pipePath, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT | PIPE_READMODE_BYTE, PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, NULL); free(pipePath); if (hListenPipe == INVALID_HANDLE_VALUE) { return -8; } if (! SetHandleInformation(hListenPipe, HANDLE_FLAG_INHERIT, TRUE)) { return -9; } pseudoFd = Win32NewDescriptor(listenType, (int) hListenPipe, -1); if (pseudoFd == -1) { CloseHandle(hListenPipe); return -10; } hListen = (HANDLE) hListenPipe; } return pseudoFd; }
int main(int argc, char *argv[]) { IonIpc ipcs[MAX_ION_IPCS]; int ipcsCount = 0; HANDLE hPipe = INVALID_HANDLE_VALUE; int ionRunning = 1; BOOL fConnected = FALSE; char msg[5]; DWORD bytesRead; BOOL fSuccess = FALSE; IonIpcType type; DWORD key; int i; char reply[1] = { '\0' }; DWORD bytesWritten; hPipe = CreateNamedPipe("\\\\.\\pipe\\ion.pipe", PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, sizeof reply, sizeof msg, 0, NULL); if (hPipe == INVALID_HANDLE_VALUE) { printf("winion failed creating pipe, error code %u.\n", (unsigned int) GetLastError()); return 0; } memset((char *) ipcs, 0, sizeof ipcs); signal(SIGINT, SIG_IGN); while (ionRunning) { fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); if (!fConnected) { printf("winion failed on connect, error code %u.\n", (unsigned int) GetLastError()); break; } /* Read one request to retain a handle. */ fSuccess = ReadFile(hPipe, msg, sizeof msg, &bytesRead, NULL); if (!fSuccess || bytesRead == 0) { if (GetLastError() == ERROR_BROKEN_PIPE) { CloseHandle(hPipe); continue; } printf("winion failed reading msg, error code %u.\n", (unsigned int) GetLastError()); break; } /* Parse the message, open and retain the handle. */ reply[0] = 1; /* Okay. */ switch (msg[0]) { case 0: /* Stop. */ ionRunning = 0; continue; case 1: type = IonSmSegment; break; case 2: type = IonSemaphore; break; case '?': printf("winion retaining %d IPCs.\n", ipcsCount); reply[0] = 0; /* Dummy. */ break; default: reply[0] = 0; /* Fail. */ } if (reply[0]) /* Valid IPC type. */ { memcpy((char *) &key, msg + 1, sizeof(DWORD)); for (i = 0; i < ipcsCount; i++) { if (ipcs[i].type == type && ipcs[i].key == key) { break; } } if (i == ipcsCount) /* New IPC. */ { if (i == MAX_ION_IPCS) { reply[0] = 0; /* Fail. */ } else { if (noteIpc(&ipcs[i], type, (int) key)) { reply[0] = 0; } else { ipcsCount++; } } } } /* Tell the client to continue. */ fSuccess = WriteFile(hPipe, reply, sizeof reply, &bytesWritten, NULL); if (!fSuccess || bytesWritten != sizeof reply) { printf("winion failed writing reply, error code %u.\n", (unsigned int) GetLastError()); break; } /* Now disconnect pipe so it can be reconnected. */ FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); } /* Disconnect pipe and terminate. */ FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); /* Termination of process closes all handles. */ return 0; }
bool decompress(const char* in, const uint32_t inLen, unsigned char* out, size_t* ol) { uint32_t u32; uint64_t u64; ostringstream oss; string s; string cpipe; string upipe; ScopedCleaner cleaner; int fd = -1; if (!Ctlshmptr) initCtlShm(); bi::scoped_lock<bi::interprocess_mutex> cfLock(Ctlshmptr->controlFifoMutex, bi::defer_lock); #ifndef _MSC_VER pthread_t thdid = pthread_self(); #else DWORD thdid = GetCurrentThreadId(); #endif #ifdef _MSC_VER oss << "\\\\.\\pipe\\cdatafifo" << thdid; s = oss.str(); cpipe = s + ".c"; upipe = s + ".u"; HANDLE cpipeh; cpipeh = CreateNamedPipe(cpipe.c_str(), PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_WAIT, 1, 0, 8192, 0, 0); idbassert_s(cpipeh != INVALID_HANDLE_VALUE, "while creating cdata fifo"); //if (cpipeh == INVALID_HANDLE_VALUE) // throw runtime_error("while creating cdata fifo"); cleaner.cpipeh = cpipeh; HANDLE upipeh; upipeh = CreateNamedPipe(upipe.c_str(), PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_WAIT, 1, 8192, 0, 0, 0); idbassert_s(upipeh != INVALID_HANDLE_VALUE, "while creating udata fifo"); //if (upipeh == INVALID_HANDLE_VALUE) // throw runtime_error("while creating udata fifo"); cleaner.upipeh = upipeh; #else oss << "/tmp/cdatafifo" << hex << thdid; s = oss.str(); cpipe = s + ".c"; upipe = s + ".u"; cleaner.cpipename = cpipe; cleaner.upipename = upipe; unlink(cpipe.c_str()); idbassert_s(mknod(cpipe.c_str(), S_IFIFO|0666, 0) == 0, "while creating cdata fifo"); //if (mknod(cpipe.c_str(), S_IFIFO|0666, 0) != 0) // throw runtime_error("while creating cdata fifo"); unlink(upipe.c_str()); idbassert_s(mknod(upipe.c_str(), S_IFIFO|0666, 0) == 0, "while creating udata fifo"); //if (mknod(upipe.c_str(), S_IFIFO|0666, 0) != 0) // throw runtime_error("while creating udata fifo"); #endif int rc = -1; fd = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); #ifdef _MSC_VER idbassert_s(fd != INVALID_SOCKET, string("socket create error: ") + strerror(errno)); #else idbassert_s(fd >= 0, string("socket create error: ") + strerror(errno)); #endif cleaner.ctlsock = fd; struct sockaddr_in serv_addr; struct in_addr la; ::inet_aton("127.0.0.1", &la); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = la.s_addr; serv_addr.sin_port = htons(DSPort); const int MaxTries = 30; int tries = 0; again: cfLock.lock(); rc = ::connect(fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if (rc < 0) { #ifdef _MSC_VER int x = WSAGetLastError(); if (x == WSAECONNREFUSED) #else if (errno == ECONNREFUSED) #endif { idbassert_s(++tries < MaxTries, string("socket connect error: ") + strerror(errno)); //if (++tries >= MaxTries) // throw runtime_error(string("socket connect error: ") + strerror(errno)); cfLock.unlock(); sleep(2); goto again; } idbassert_s(0, string("socket connect error: ") + strerror(errno)); //throw runtime_error(string("socket connect error: ") + strerror(errno)); } u32 = s.length(); sendn(fd, reinterpret_cast<const char*>(&u32), 4); sendn(fd, s.c_str(), u32); shutdown(fd, SHUT_RDWR); #ifdef _MSC_VER closesocket(fd); cleaner.ctlsock = INVALID_SOCKET; #else close(fd); cleaner.ctlsock = -1; #endif cfLock.unlock(); #ifdef _MSC_VER BOOL dwrc; dwrc = ConnectNamedPipe(cpipeh, 0); idbassert_s(!(dwrc == 0 && GetLastError() != ERROR_PIPE_CONNECTED), "connecting to cpipe"); //if (dwrc == 0 && GetLastError() != ERROR_PIPE_CONNECTED) // throw runtime_error("connecting to cpipe"); u64 = static_cast<uint64_t>(inLen); idbassert_s(u64 < 8 * 1024 * 1024, "preposterous inLen!"); //if (!(u64 < 8 * 1024 * 1024)) // throw runtime_error("preposterous inLen!"); DWORD nwrite; dwrc = WriteFile(cpipeh, &u64, 8, &nwrite, 0); idbassert_s(dwrc != 0 && nwrite == 8, "while writing to cpipe"); //if (!(dwrc != 0 && nwrite == 8)) // throw runtime_error("while writing to cpipe"); dwrc = WriteFile(cpipeh, in, u64, &nwrite, 0); idbassert_s(dwrc != 0 && nwrite == u64, "while writing to cpipe"); //if (!(dwrc != 0 && nwrite == u64)) // throw runtime_error("while writing to cpipe"); FlushFileBuffers(cpipeh); CloseHandle(cpipeh); cleaner.cpipeh = INVALID_HANDLE_VALUE; #else ssize_t wrc; fd = open(cpipe.c_str(), O_WRONLY); idbassert_s(fd >= 0, "while opening data fifo for write"); //if (fd < 0) // throw runtime_error("while opening data fifo for write"); cleaner.fd = fd; u64 = static_cast<uint64_t>(inLen); errno = 0; wrc = writen(fd, &u64, 8); int err = errno; idbassert_s(wrc == 8, string("while writing compressed len to the DS: ") + strerror(err)); // if (wrc != 8) // { // ostringstream oss; // oss << "while writing compressed len to the DS: " << strerror(err); // throw runtime_error(oss.str()); // } wrc = writen(fd, in, u64); idbassert_s(wrc == static_cast<ssize_t>(u64), "while writing compressed data to the DS"); // if (wrc != static_cast<ssize_t>(u64)) // throw runtime_error("while writing compressed data to the DS"); close(fd); cleaner.fd = -1; #endif #ifdef _MSC_VER dwrc = ConnectNamedPipe(upipeh, 0); idbassert_s(!(dwrc == 0 && GetLastError() != ERROR_PIPE_CONNECTED), "connecting to upipe"); //if (dwrc == 0 && GetLastError() != ERROR_PIPE_CONNECTED) // throw runtime_error("connecting to upipe"); DWORD nread; dwrc = ReadFile(upipeh, &u64, 8, &nread, 0); idbassert_s(dwrc != 0 && nread == 8, "while reading from upipe"); //if (!(dwrc != 0 && nread == 8)) // throw runtime_error("while reading from upipe"); dwrc = ReadFile(upipeh, out, u64, &nread, 0); idbassert_s(dwrc != 0 && nread == u64, "while reading from upipe"); //if (!(dwrc != 0 && nread == u64)) // throw runtime_error("while reading from upipe"); CloseHandle(upipeh); cleaner.upipeh = INVALID_HANDLE_VALUE; #else fd = open(upipe.c_str(), O_RDONLY); idbassert_s(fd >= 0, "while opening data fifo for read"); // if (fd < 0) // throw runtime_error("while opening data fifo for read"); cleaner.fd = fd; readn(fd, &u64, 8); readn(fd, out, u64); close(fd); cleaner.fd = -1; #endif *ol = static_cast<size_t>(u64); return (u64 != 0); }
INT_PTR CALLBACK ShellProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { int idx; PWSTR exePath; wchar_t addrString[16]; DWORD address; switch (uMsg) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: { int ccnt=GetDlgItemText(hwndDlg,IDC_ADDRESS,addrString,15); if(ccnt==0) address=0; else if(!StrToIntEx(addrString,STIF_SUPPORT_HEX,(int*)&address)) { MessageBox(hwndDlg,L"Function address must be a hex number.",0,0); break; } int len=GetWindowTextLength(GetDlgItem(hwndDlg,IDC_EXEPATH)); if(len==0) { MessageBox(hwndDlg,L"Please select the exe file",0,0); break; } exePath=new wchar_t[len+1]; if(exePath==0) { delete[] exePath; MessageBox(hwndDlg,L"Not enough memory",0,0); break; } GetDlgItemText(hwndDlg,IDC_EXEPATH,exePath,len+1); STARTUPINFO si; memset1(&si,0,sizeof(si)); si.cb=sizeof(si); PROCESS_INFORMATION pi; if(!CreateProcess(0,exePath,0,0,FALSE,CREATE_SUSPENDED,0,0,&si,&pi)) { delete[] exePath; MessageBox(hwndDlg,L"Can't start exe!",0,0); break; } delete[] exePath; int pathLen=256; wchar_t* dllPath=new wchar_t[pathLen]; int retlen=GetModuleFileName(0,dllPath,pathLen); while(GetLastError()==ERROR_INSUFFICIENT_BUFFER) { delete[] dllPath; pathLen*=2; dllPath=new wchar_t[pathLen]; retlen=GetModuleFileName(0,dllPath,pathLen); }; wchar_t* p=dllPath+retlen; for(;p>dllPath;p--) if(*p==L'\\') break; *(p+1)=L'\0'; lstrcat(dllPath,L"extractor.dll"); int rslt=InjectToProcess(pi.hProcess,pi.hThread,dllPath,(DecoprFunc)address); delete[] dllPath; if(rslt<0) { MessageBox(hwndDlg,L"Failed to inject process",0,0); break; } wchar_t pipeName[30]; wsprintf(pipeName,PIPE_NAME,pi.dwProcessId); HANDLE pipe=CreateNamedPipe(pipeName,PIPE_ACCESS_DUPLEX,PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,256,256,0,0); if(pipe==INVALID_HANDLE_VALUE) { MessageBox(hwndDlg,L"Faild to create pipe",0,0); TerminateProcess(pi.hProcess,0); break; } ResumeThread(pi.hThread); rslt=PipeComm(pipe,address); CloseHandle(pipe); if(rslt<0) { MessageBox(hwndDlg,L"Failed to communicated with sub process",0,0); break; } } // Fall through. case IDCANCEL: EndDialog(hwndDlg, wParam); return TRUE; case IDC_ADDRESS: if(HIWORD(wParam)==EN_CHANGE) { idx=SendDlgItemMessage(hwndDlg,IDC_GAMELIST,CB_GETCURSEL,0,0); if(idx<g_gameCount) { int cnt=GetDlgItemText(hwndDlg,IDC_ADDRESS,addrString,15); if(cnt==0) SendDlgItemMessage(hwndDlg,IDC_GAMELIST,CB_SETCURSEL,0,0); else if(idx!=CB_ERR && !(StrToIntEx(addrString,STIF_SUPPORT_HEX,(int*)&address) && address==g_gameList[idx].funcAddress)) SendDlgItemMessage(hwndDlg,IDC_GAMELIST,CB_SETCURSEL,-1,0); } } break; case IDC_GAMELIST: switch (HIWORD(wParam)) { case CBN_SELCHANGE: idx=SendDlgItemMessage(hwndDlg,IDC_GAMELIST,CB_GETCURSEL,0,0); if(idx==0) { SetDlgItemText(hwndDlg,IDC_ADDRESS,L""); } else if(idx!=CB_ERR && idx<g_gameCount) { wsprintf(addrString,L"0x%X",g_gameList[idx].funcAddress); SetDlgItemText(hwndDlg,IDC_ADDRESS,addrString); } break; } break; case IDC_BROWSE: if(SUCCEEDED(BasicFileOpen(&exePath))) { SetDlgItemText(hwndDlg,IDC_EXEPATH,exePath); CoTaskMemFree(exePath); } break; case IDC_ABOUT: MessageBox(hwndDlg,L"fxckBGI - an extractor for BGI engine.\n\tv" PRODUCT_VERSION L" by AmaF",L"About",MB_ICONINFORMATION); break; } break; case WM_INITDIALOG: g_hwnd=hwndDlg; HICON icon=LoadIcon(g_hInstance,(LPCWSTR)IDI_ICON1); SendMessage(hwndDlg,WM_SETICON,ICON_SMALL,(LPARAM)icon); for(int i=0;i<g_gameCount;i++) { SendDlgItemMessage(hwndDlg,IDC_GAMELIST,CB_ADDSTRING,0,(LPARAM)(g_gameList[i].gameName)); } SendDlgItemMessage(hwndDlg,IDC_GAMELIST,CB_SETCURSEL,0,0); return TRUE; } return FALSE; }
// PURPOSE: starts the service. (synchronous) int CNTService::ServiceStart(DWORD dwArgc, LPTSTR *lpszArgv) { ReportEvent(EVENTLOG_INFORMATION_TYPE, 0, "Service start pending."); // Service initialization report status to the service control manager. int rc = -1; if ( !SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000) ) return rc; // Create the event object. The control handler function signals this event when it receives a "stop" control code m_hServerStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if ( !m_hServerStopEvent ) return rc; if ( !SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000) ) { bailout1: CloseHandle(m_hServerStopEvent); return rc; } // Create the event object used in overlapped i/o HANDLE hEvents[2] = {NULL, NULL}; hEvents[0] = m_hServerStopEvent; hEvents[1] = CreateEvent(NULL, TRUE, FALSE, NULL); if ( !hEvents[1] ) goto bailout1; if ( !SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000) ) { bailout2: CloseHandle(hEvents[1]); goto bailout1; } // Create a security descriptor that allows anyone to write to the pipe PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR) malloc(SECURITY_DESCRIPTOR_MIN_LENGTH); if ( !pSD ) goto bailout2; if ( !InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION) ) { bailout3: free(pSD); goto bailout2; } // Add a NULL descriptor ACL to the security descriptor if ( !SetSecurityDescriptorDacl(pSD, TRUE, NULL, FALSE) ) goto bailout3; SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = pSD; sa.bInheritHandle = TRUE; if ( !SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000) ) goto bailout3; // Set the name of the named pipe this application uses. We create a named pipe to ensure that // only one instance of this application runs on the machine at a time. If there is an instance // running, it will own this pipe, and any further attempts to create the same named pipe will fail. char lpszPipeName[80]; sprintf(lpszPipeName, "\\\\.\\pipe\\" SPHERE_FILE "svr\\%s", g_Serv.GetName()); char szErr[256]; // Open the named pipe HANDLE hPipe = CreateNamedPipe(lpszPipeName, FILE_FLAG_OVERLAPPED|PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT, 1, 0, 0, 1000, &sa); if ( hPipe == INVALID_HANDLE_VALUE ) { ReportEvent(EVENTLOG_ERROR_TYPE, 0, "Can't create named pipe. Check multi-instance?", GetLastErrorText(szErr, sizeof(szErr))); goto bailout3; } if ( SetServiceStatus(SERVICE_RUNNING, NO_ERROR, 0) ) { rc = Sphere_MainEntryPoint(dwArgc, lpszArgv); if ( !rc ) ReportEvent(EVENTLOG_INFORMATION_TYPE, 0, "service stopped", GetLastErrorText(szErr, sizeof(szErr))); else { char szMessage[80]; sprintf(szMessage, "%d.", rc); ReportEvent(EVENTLOG_ERROR_TYPE, 0, "service stopped abnormally", szMessage); } } else ReportEvent(EVENTLOG_ERROR_TYPE, 0, "ServiceStart failed."); CloseHandle(hPipe); goto bailout3; }
DWORD WINAPI Transporter(LPVOID lpParam) { HANDLE hPipeClient; //connected to store pipe as client //connect loop while (TRUE) { hPipeClient = CreateFile ( lpstrStorePipeName, //pipe name GENERIC_READ | //read/write access GENERIC_WRITE, 0, //no sharing NULL, //default security attributes OPEN_EXISTING, //open existing pipe 0, //default attributes NULL //no template file ); if (hPipeClient != INVALID_HANDLE_VALUE) { break; } } //pipe connected //change to message-read mode BOOL fSuccess; DWORD dwMode = PIPE_READMODE_MESSAGE; fSuccess = SetNamedPipeHandleState( hPipeClient, //pipe handle &dwMode, //new pipe mode NULL, //don`t set maximum size NULL //don`t set maximum time ); if (!fSuccess) { CloseHandle(hPipeClient); return (EXIT_FAILURE); } //create pipe for power block threads HANDLE hPipe; hPipe = CreateNamedPipe( lpstrTransporterPipeName, //pipe name PIPE_ACCESS_DUPLEX, //read/write access PIPE_TYPE_MESSAGE | //message type pipe PIPE_READMODE_MESSAGE | //message-read mode PIPE_WAIT, //blocking mode 1, //max instances cbufsize, //output buffer size cbufsize, //input buffer size 0, //client time-out NULL //default security attributes ); if (hPipe == INVALID_HANDLE_VALUE) { CloseHandle(hPipeClient); return (EXIT_FAILURE); } //general loop int fuelWeight = 0; int emptyBlock = 0; int cap = 0; unsigned long cbBytesWrite = 0; unsigned long cbBytesRead = 0; while (TRUE) { //check terminate flag if (terminate) { //disconnect client FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); //disconnect from server CloseHandle(hPipeClient); break; } //initial transport position setfillstyle(1, cGREY); bar(30, 260, 50, 280); //write to store pipe that transporter is arrived //and wait for fuel weight from store fSuccess = TransactNamedPipe( hPipeClient, //handle to pipe &cap, //address of write data variable cbufsize, //size of write data variable &fuelWeight, //address of store data variable cbufsize, //size of store data variable &cbBytesRead, //number of bytes read NULL //not overlapped I/O ); //transaction is failed if (!fSuccess || cbBytesRead == 0) { //disconnect client FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); //disconnect from server CloseHandle(hPipeClient); return (EXIT_FAILURE); } //visualisation of loading state setfillstyle(1, cGREEN); bar(30, 260, 50, 280); //waiting for the first empty power block ConnectNamedPipe(hPipe, NULL); //take index of empty power block fSuccess = ReadFile( hPipe, //handle to pipe &emptyBlock, //address of store data variable cbufsize, //size of store data variable &cbBytesRead, //number of bytes read NULL //not overlapped I/O ); //read was failed if (!fSuccess || cbBytesRead == 0) { //disconnect client FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); //disconnect from server CloseHandle(hPipeClient); return (EXIT_FAILURE); } //visualisation of transferring fuel to appropriate power block for (int i = 0; i < emptyBlock * 80 + 80; ++i) { setfillstyle(1, cGREEN); bar(i + 30, 260, i + 50, 280); delay(SUSPEND_FACT / 50); setfillstyle(1, cWHITE); bar(i + 30, 260, i + 50, 280); } //unload transport position setfillstyle(1, cGREEN); bar(emptyBlock * 80 + 110, 260, emptyBlock * 80 + 130, 280); //write that transporter is arrived to power block fSuccess = WriteFile( hPipe, //handle to pipe &fuelWeight, //address of write data variable cbufsize, //number of bytes to write &cbBytesWrite, //number of bytes written NULL //not overlapped I/O ); //write was failed if (!fSuccess || cbBytesWrite != cbufsize) { //disconnect client FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); //disconnect from server CloseHandle(hPipeClient); return (EXIT_FAILURE); } //waiting until power block is filled fSuccess = ReadFile( hPipe, //handle to pipe &cap, //address of store data variable cbufsize, //size of store data variable &cbBytesRead, //number of bytes read NULL //not overlapped I/O ); //read was failed if (!fSuccess || cbBytesRead == 0) { //disconnect client FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); //disconnect from server CloseHandle(hPipeClient); return (EXIT_FAILURE); } //disconnect client FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); //visualisation of transferring back to store fuel item for (int i = emptyBlock * 80 + 80; i >= 0; --i) { setfillstyle(1, cGREY); bar(i + 30, 260, i + 50, 280); delay(SUSPEND_FACT / 100); setfillstyle(1, cWHITE); bar(i + 30, 260, i + 50, 280); } } return (EXIT_SUCCESS); }
void PipeServer() { HANDLE hPipeToSrv; HANDLE hPipeFromSrv; LPTSTR pipeNameToSrv= _T("\\\\.\\pipe\\ToSrvPipe"); hPipeToSrv = CreateNamedPipe( pipeNameToSrv , PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, PIPE_UNLIMITED_INSTANCES, nBuff, nBuff, 50,//Timeout - always send straight away. NULL); if( hPipeToSrv == INVALID_HANDLE_VALUE) return; LPTSTR pipeNameFromSrv= __T("\\\\.\\pipe\\FromSrvPipe"); hPipeFromSrv = CreateNamedPipe( pipeNameFromSrv , PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, PIPE_UNLIMITED_INSTANCES, nBuff, nBuff, 50,//Timeout - always send straight away. NULL); if( hPipeFromSrv == INVALID_HANDLE_VALUE) return; BOOL bConnected; BOOL bSuccess; DWORD cbBytesRead; DWORD cbBytesWritten; CHAR chRequest[ nBuff ]; CHAR chResponse[ nBuff ]; int jj=0; for(;;) { printf( "Obtaining pipe\n" ); bConnected = ConnectNamedPipe(hPipeToSrv, NULL) ? TRUE : (GetLastError()==ERROR_PIPE_CONNECTED ); printf( "Obtained to-srv %i\n", bConnected ); bConnected = ConnectNamedPipe(hPipeFromSrv, NULL) ? TRUE : (GetLastError()==ERROR_PIPE_CONNECTED ); printf( "Obtained from-srv %i\n", bConnected ); if( bConnected ) { for(;;) { printf( "About to read\n" ); bSuccess = ReadFile( hPipeToSrv, chRequest, nBuff, &cbBytesRead, NULL); chRequest[ cbBytesRead] = '\0'; if( !bSuccess || cbBytesRead==0 ) break; printf( "Rxd %s\n", chRequest ); DoSrv( chRequest ); jj++; while( true ) { int nWritten = DoSrvMore( chResponse, nBuff ); if( nWritten <= 1 ) break; WriteFile( hPipeFromSrv, chResponse, nWritten-1, &cbBytesWritten, NULL); } //FlushFileBuffers( hPipeFromSrv ); } FlushFileBuffers( hPipeToSrv ); DisconnectNamedPipe( hPipeToSrv ); FlushFileBuffers( hPipeFromSrv ); DisconnectNamedPipe( hPipeFromSrv ); break; } else { CloseHandle( hPipeToSrv ); CloseHandle( hPipeFromSrv ); } } CloseHandle( hPipeToSrv ); CloseHandle( hPipeFromSrv ); }