Exemple #1
0
	BOOL CreateAndConnectInstance(LPOVERLAPPED lpoOverlap)
	{
		if (!(hdPipe = CreateNamedPipe(pipeName,PIPE_ACCESS_DUPLEX |FILE_FLAG_OVERLAPPED,
			PIPE_TYPE_MESSAGE |	PIPE_READMODE_MESSAGE |	PIPE_WAIT,
			PIPE_UNLIMITED_INSTANCES,BUFSIZE*sizeof(TCHAR),BUFSIZE*sizeof(TCHAR),
			PIPE_TIMEOUT,NULL)))
			return 0*(printf("CreateNamedPipe failed with %ld.\n", GetLastError()));
		return ConnectToNewClient(hdPipe, lpoOverlap);
	}
Exemple #2
0
    VOID Server::DisconnectAndReconnect(DWORD pipe_number)
    { 
        // Disconnect the pipe instance.
        if (! DisconnectNamedPipe(Pipe_[pipe_number].hPipeInst)) 
        {
            // TODO: Убрать (заменить) логирование.
            printf("DisconnectNamedPipe failed with %d.\n", GetLastError());

            Pipe_[pipe_number].dwState = STATE::errored;
        }

        Pipe_[pipe_number].dwState = STATE::undefined;

        // Call a subroutine to connect to the new client. 
        ConnectToNewClient(pipe_number);
    }
Exemple #3
0
VOID DisconnectAndReconnect(DWORD i) 
{ 
// Disconnect the pipe instance. 
 
   if (! DisconnectNamedPipe(Pipe[i].hPipeInst) ) 
   {
      printf("DisconnectNamedPipe failed with %d.\n", GetLastError());
   }
 
// Call a subroutine to connect to the new client. 
 
   Pipe[i].fPendingIO = ConnectToNewClient( 
      Pipe[i].hPipeInst, 
      &Pipe[i].oOverlap); 
 
   Pipe[i].dwState = Pipe[i].fPendingIO ? 
      CONNECTING_STATE : // still connecting 
      READING_STATE;     // ready to read 
} 
void
NamedPipeServer::run()
{
   DWORD i, dwWait, cbRet, dwErr;
   BOOL fSuccess;
   QByteArray response;

   std::string s;
   DWORD r = scrobSubPipeName( &s );
   if (r != 0) throw std::runtime_error( formatWin32Error( r ) );
   QString const name = QString::fromStdString( s );

// The initial loop creates several instances of a named pipe
// along with an event object for each instance.  An
// overlapped ConnectNamedPipe operation is started for
// each instance.

   for (i = 0; i < INSTANCES; i++)
   {

   // Create an event object for this instance.

      hEvents[i] = CreateEvent(
         NULL,    // default security attribute
         TRUE,    // manual-reset event
         TRUE,    // initial state = signaled
         NULL);   // unnamed event object

      if (hEvents[i] == NULL)
      {
         printf("CreateEvent failed with %d.\n", GetLastError());
         return;
      }

      Pipe[i].oOverlap.hEvent = hEvents[i];

      Pipe[i].hPipeInst = CreateNamedPipe(
         (const wchar_t *)name.utf16(),            // 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
         INSTANCES,               // number of instances
         BUFSIZE*sizeof(TCHAR),   // output buffer size
         BUFSIZE*sizeof(TCHAR),   // input buffer size
         PIPE_TIMEOUT,            // client time-out
         NULL);                   // default security attributes

      if (Pipe[i].hPipeInst == INVALID_HANDLE_VALUE)
      {
         printf("CreateNamedPipe failed with %d.\n", GetLastError());
         return;
      }

   // Call the subroutine to connect to the new client

      Pipe[i].fPendingIO = ConnectToNewClient(
         Pipe[i].hPipeInst,
         &Pipe[i].oOverlap);

      Pipe[i].dwState = Pipe[i].fPendingIO ?
         CONNECTING_STATE : // still connecting
         READING_STATE;     // ready to read
   }

   while (1)
   {
   // Wait for the event object to be signaled, indicating
   // completion of an overlapped read, write, or
   // connect operation.

      dwWait = WaitForMultipleObjects(
         INSTANCES,    // number of event objects
         hEvents,      // array of event objects
         FALSE,        // does not wait for all
         INFINITE);    // waits indefinitely

   // dwWait shows which pipe completed the operation.

      i = dwWait - WAIT_OBJECT_0;  // determines which pipe
      if (i < 0 || i > (INSTANCES - 1))
      {
         printf("Index out of range.\n");
         return;
      }

   // Get the result if the operation was pending.

      if (Pipe[i].fPendingIO)
      {
         fSuccess = GetOverlappedResult(
            Pipe[i].hPipeInst, // handle to pipe
            &Pipe[i].oOverlap, // OVERLAPPED structure
            &cbRet,            // bytes transferred
            FALSE);            // do not wait

         switch (Pipe[i].dwState)
         {
         // Pending connect operation
            case CONNECTING_STATE:
               if (! fSuccess)
               {
                   printf("Error %d.\n", GetLastError());
                   return;
               }
               Pipe[i].dwState = READING_STATE;
               break;

         // Pending read operation
            case READING_STATE:
               if (! fSuccess || cbRet == 0)
               {
                  DisconnectAndReconnect(i);
                  continue;
               }
               Pipe[i].cbRead = cbRet;
               Pipe[i].dwState = WRITING_STATE;
               break;

         // Pending write operation
            case WRITING_STATE:
               if (! fSuccess || cbRet != Pipe[i].cbToWrite)
               {
                  DisconnectAndReconnect(i);
                  continue;
               }
               Pipe[i].dwState = READING_STATE;
               break;

            default:
            {
               printf("Invalid pipe state.\n");
               return;
            }
         }
      }

   // The pipe state determines which operation to do next.

      switch (Pipe[i].dwState)
      {
      // READING_STATE:
      // The pipe instance is connected to the client
      // and is ready to read a request from the client.

         case READING_STATE:
            fSuccess = ReadFile(
               Pipe[i].hPipeInst,
               Pipe[i].chRequest,
               BUFSIZE*sizeof(TCHAR),
               &Pipe[i].cbRead,
               &Pipe[i].oOverlap);

         // The read operation completed successfully.

            if (fSuccess && Pipe[i].cbRead != 0)
            {
               Pipe[i].fPendingIO = FALSE;
               Pipe[i].dwState = WRITING_STATE;
               continue;
            }

         // The read operation is still pending.

            dwErr = GetLastError();
            if (! fSuccess && (dwErr == ERROR_IO_PENDING))
            {
               Pipe[i].fPendingIO = TRUE;
               continue;
            }

         // An error occurred; disconnect from the client.

            DisconnectAndReconnect(i);
            break;

      // WRITING_STATE:
      // The request was successfully read from the client.
      // Get the reply data and write it to the client.

         case WRITING_STATE:
            response = emit lineReady( QString::fromUtf8( (char*)Pipe[i].chRequest, Pipe[i].cbRead ) ).toUtf8();
            StringCchCopy( Pipe[i].chReply, BUFSIZE, (LPCTSTR)response.data() );
            Pipe[i].cbToWrite = response.size();

            fSuccess = WriteFile(
               Pipe[i].hPipeInst,
               Pipe[i].chReply,
               Pipe[i].cbToWrite,
               &cbRet,
               &Pipe[i].oOverlap);

         // The write operation completed successfully.

            if (fSuccess && cbRet == Pipe[i].cbToWrite)
            {
               Pipe[i].fPendingIO = FALSE;
               Pipe[i].dwState = READING_STATE;
               continue;
            }

         // The write operation is still pending.

            dwErr = GetLastError();
            if (! fSuccess && (dwErr == ERROR_IO_PENDING))
            {
               Pipe[i].fPendingIO = TRUE;
               continue;
            }

         // An error occurred; disconnect from the client.

            DisconnectAndReconnect(i);
            break;

         default:
         {
            printf("Invalid pipe state.\n");
            return;
         }
      }
  }
}
Exemple #5
0
    DWORD Server::Start_Helper(VOID)
    {
        // Предотвращение повторного запуска.
        hServerIsUp_Mutex = CreateMutexA(NULL, FALSE,  SERVER_IS_WORKING_MUTEX_GUID);
        if ((hServerIsUp_Mutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS))
        {
            CLOSE_HANDLE(hServerIsUp_Mutex);

            return ERROR_ALREADY_EXISTS;
        }

        DWORD i;

        // The initial loop creates several S_PIPES_INSTANCES of a named pipe 
        // along with an event object for each instance.  An 
        // overlapped ConnectNamedPipe operation is started for 
        // each instance. 

        for (i = 0; i < S_PIPES_INSTANCES; i++) 
        {
            // Create an event object for this instance.
            CREATE_EVENT__SIGNALED(hPipes_Events_[i], t_string(TEXT("!!!!!_") + t_to_string(i)).c_str());

            if (hPipes_Events_[i] == NULL) 
            {     
                return GetLastError();   
            }

            Pipe_[i].oOverlap.hEvent = hPipes_Events_[i]; 

            Pipe_[i].hPipeInst = CreateNamedPipe(             
                                                    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 
                                                    S_PIPES_INSTANCES,                              // number of S_PIPES_INSTANCES 
                                                    BUFSIZE*sizeof(TCHAR),                          // output buffer size 
                                                    BUFSIZE*sizeof(TCHAR),                          // input buffer size 
                                                    S_PIPE_TIMEOUT,                                 // client time-out 
                                                    NULL                                            // default security attributes 
                                                );

            if (Pipe_[i].hPipeInst == INVALID_HANDLE_VALUE) 
            {
                return GetLastError();
            }

            // Call the subroutine to connect to the new client            
            if (DWORD connect_to_new_client_result = ConnectToNewClient(i) != ERROR_SUCCESS) 
            {
                return connect_to_new_client_result;
            }  
        }

        // stop-event
        CREATE_EVENT__UNSIGNALED(hPipes_Events_[S_EVENT_STOP], TEXT(""));
        // stop-server-event
        CREATE_EVENT__UNSIGNALED(hPipes_Events_[S_EVENT_STOP_SERVER], TEXT(STOP_SERVER_EVENT_GUID));

        for (DWORD counter = 0; counter < S_EVENTS_; counter++ )
        {
            CREATE_EVENT__UNSIGNALED(hS_Events_[counter], TEXT(""));
        }

        //TODO_URGENT: инициализировать S_EVENTS_

        InitializeCriticalSection(&csReadPipe_);
        for (DWORD counter = 0; counter < S_PIPES_INSTANCES; counter++)
        {        
            InitializeCriticalSection(&Pipe_[counter].csWritePipe);
        }    

        StartMainThread();

        eState_ = STATE::started;

        return ERROR_SUCCESS;
    }
int PipeManager(LPTSTR lpszPipename, void __cdecl GetAnswerToRequest(LPPIPEINST pipe))
{
    DWORD i, dwWait, cbRet, dwErr; 
    BOOL fSuccess; 

    char pTemp[121];

    // The initial loop creates several instances of a named pipe 
    // along with an event object for each instance.  An 
    // overlapped ConnectNamedPipe operation is started for 
    // each instance. 
    for (i = 0; i < INSTANCES; i++) 
    { 

        // create named pipe
        Pipe[i].sa.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
        if (!InitializeSecurityDescriptor(Pipe[i].sa.lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
        {
            sprintf_s(pTemp, 120, "PipeManager: InitializeSecurityDescriptor failed, error code = %d", GetLastError());
            WriteLog(pTemp);
            return 0;
        }
        if (!SetSecurityDescriptorDacl(Pipe[i].sa.lpSecurityDescriptor, TRUE, (PACL)0, FALSE))
        {
            sprintf_s(pTemp, 120, "PipeManager: SetSecurityDescriptorDacl failed, error code = %d", GetLastError());
            WriteLog(pTemp);
            return 0;
        }
        Pipe[i].sa.nLength = sizeof Pipe[i].sa;
        Pipe[i].sa.bInheritHandle = TRUE;

        // Create an event object for this instance. 
        hEvents[i] = CreateEvent( 
                NULL,    // default security attribute 
                TRUE,    // manual-reset event 
                TRUE,    // initial state = signaled 
                NULL);   // unnamed event object 

        if (hEvents[i] == NULL) 
        {
            sprintf_s(pTemp, 120, "PipeManager: CreateEvent failed with %d.\n", GetLastError()); 
            WriteLog(pTemp);
            return 0;
        }

        Pipe[i].oOverlap.hEvent = hEvents[i]; 

        Pipe[i].hPipeInst = CreateNamedPipe( 
                lpszPipename,            // 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 
                INSTANCES,               // number of instances 
                BUFSIZE*sizeof(TCHAR),   // output buffer size 
                BUFSIZE*sizeof(TCHAR),   // input buffer size 
                PIPE_TIMEOUT,            // client time-out 
                &Pipe[i].sa);             // the security attributes 

        if (Pipe[i].hPipeInst == INVALID_HANDLE_VALUE) 
        {
            sprintf_s(pTemp, 120, "PipeManager: CreateNamedPipe failed with %d.\n", GetLastError());
            WriteLog(pTemp);
            return 0;
        }

        // Call the subroutine to connect to the new client
        Pipe[i].fPendingIO = ConnectToNewClient( 
                Pipe[i].hPipeInst, 
                &Pipe[i].oOverlap); 

        Pipe[i].dwState = Pipe[i].fPendingIO ? 
            CONNECTING_STATE : // still connecting 
            READING_STATE;     // ready to read 
    } 

    // Create an event object used to signal that PipeManager shuld exit. 
    hEvents[INSTANCES] = CreateEvent( 
            NULL,    // default security attribute 
            TRUE,    // manual-reset event 
            FALSE,    // initial state = not signaled 
            NULL);   // unnamed event object 

    if (hEvents[INSTANCES] == NULL) 
    {
        sprintf_s(pTemp, 120, "PipeManager: CreateEvent failed with %d.\n", GetLastError()); 
        WriteLog(pTemp);
        return 0;
    }

    while (true) 
    { 
        // Wait for the event object to be signaled, indicating 
        // completion of an overlapped read, write, or 
        // connect operation. 
        dwWait = WaitForMultipleObjects( 
                (INSTANCES +1),    // number of event objects 
                hEvents,      // array of event objects 
                FALSE,        // does not wait for all 
                INFINITE);    // waits indefinitely 


        // dwWait shows which pipe completed the operation. 
        i = dwWait - WAIT_OBJECT_0;  // determines which pipe 

        // If this was the exit PipeManager event, we exits the loop.
        if (i == INSTANCES) {
            break;
        }

        // Chack the range
        if (i < 0 || i > (INSTANCES - 1)) 
        {
            sprintf_s(pTemp, 120, "PipeManager: Index (%d) out of range. 0..%d\n", i, INSTANCES); 
            WriteLog(pTemp);
            return 0;
        }

        // Get the result if the operation was pending. 
        if (Pipe[i].fPendingIO) 
        { 
            fSuccess = GetOverlappedResult( 
                    Pipe[i].hPipeInst, // handle to pipe 
                    &Pipe[i].oOverlap, // OVERLAPPED structure 
                    &cbRet,            // bytes transferred 
                    FALSE);            // do not wait 

            switch (Pipe[i].dwState) 
            { 
                // Pending connect operation 
                case CONNECTING_STATE: 
                    if (! fSuccess) 
                    {
                        sprintf_s(pTemp, 120, "PipeManager, Pipe error %d.\n", GetLastError()); 
                        WriteLog(pTemp);
                        return 0;
                    }
                    Pipe[i].dwState = READING_STATE; 
                    break; 

                    // Pending read operation 
                case READING_STATE: 
                    if (! fSuccess || cbRet == 0) 
                    { 
                        DisconnectAndReconnect(i); 
                        continue; 
                    }
                    Pipe[i].cbRead = cbRet;
                    Pipe[i].dwState = WRITING_STATE; 
                    break; 

                    // Pending write operation 
                case WRITING_STATE: 
                    if (! fSuccess || cbRet != Pipe[i].cbToWrite) 
                    { 
                        DisconnectAndReconnect(i); 
                        continue; 
                    } 
                    Pipe[i].dwState = READING_STATE; 
                    break; 

                default: 
                    {
                        sprintf_s(pTemp, 120, "PipeManager: Invalid pipe state.\n"); 
                        WriteLog(pTemp);
                        return 0;
                    }
            }  
        } 

        // The pipe state determines which operation to do next. 
        switch (Pipe[i].dwState) 
        { 
            // READING_STATE: 
            // The pipe instance is connected to the client 
            // and is ready to read a request from the client. 
            case READING_STATE: 
                fSuccess = ReadFile( 
                        Pipe[i].hPipeInst, 
                        Pipe[i].chRequest, 
                        BUFSIZE*sizeof(TCHAR), 
                        &Pipe[i].cbRead, 
                        &Pipe[i].oOverlap); 

                // The read operation completed successfully.  
                if (fSuccess && Pipe[i].cbRead != 0) 
                { 
                    Pipe[i].fPendingIO = FALSE; 
                    Pipe[i].dwState = WRITING_STATE; 
                    continue; 
                } 

                // The read operation is still pending. 
                dwErr = GetLastError(); 
                if (! fSuccess && (dwErr == ERROR_IO_PENDING)) 
                { 
                    Pipe[i].fPendingIO = TRUE; 
                    continue; 
                } 

                // An error occurred; disconnect from the client. 
                DisconnectAndReconnect(i); 
                break; 

                // WRITING_STATE: 
                // The request was successfully read from the client. 
                // Get the reply data and write it to the client. 
            case WRITING_STATE: 
                GetAnswerToRequest(&Pipe[i]); 

                //make it a valid string.
                ++Pipe[i].cbToWrite;
                Pipe[i].chReply[Pipe[i].cbToWrite] = '\0';

                fSuccess = WriteFile( 
                        Pipe[i].hPipeInst, 
                        Pipe[i].chReply, 
                        Pipe[i].cbToWrite, 
                        &cbRet, 
                        &Pipe[i].oOverlap); 

                // The write operation completed successfully. 
                if (fSuccess && cbRet == Pipe[i].cbToWrite) 
                { 
                    Pipe[i].fPendingIO = FALSE; 
                    Pipe[i].dwState = READING_STATE; 
                    Pipe[i].cbToWrite = 0; //All data is writen
                    continue; 
                } 

                // The write operation is still pending. 
                dwErr = GetLastError(); 
                if (! fSuccess && (dwErr == ERROR_IO_PENDING)) 
                { 
                    Pipe[i].fPendingIO = TRUE; 
                    continue; 
                } 
                else 
                {
                    sprintf_s(pTemp, 120, "PipeManager: WRITING_STATE error 0x%x.\n", dwErr);
                    WriteLog(pTemp);
                }

                // An error occurred; disconnect from the client. 
                DisconnectAndReconnect(i); 
                break; 

            default: 
                {
                    sprintf_s(pTemp, 120, "PipeManager: Invalid pipe state.\n"); 
                    WriteLog(pTemp);
                    return 0;
                }
        } 
    } 

    return 0;


}