Пример #1
0
int main(int argc, char *argv[])
{
   BOOL fConnected;
   DWORD dwThreadId;
   HANDLE hPipe, hThread;
   LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");

//   for (;;)
//     {
	hPipe = CreateNamedPipe(lpszPipename,
				PIPE_ACCESS_DUPLEX,
				PIPE_TYPE_MESSAGE |
				PIPE_READMODE_MESSAGE |
				PIPE_WAIT,
				PIPE_UNLIMITED_INSTANCES,
				BUFSIZE,
				BUFSIZE,
				PIPE_TIMEOUT,
				NULL);
	if (hPipe == INVALID_HANDLE_VALUE)
	  {
	     printf("CreateNamedPipe() failed\n");
	     return 0;
	  }

	fConnected = ConnectNamedPipe(hPipe,
				      NULL) ? TRUE : (GetLastError () ==
					    ERROR_PIPE_CONNECTED);
	if (fConnected)
	  {
	     printf("Pipe connected!\n");

	     DisconnectNamedPipe(hPipe);

#if 0
	     hThread = CreateThread(NULL,
				    0,
				    (LPTHREAD_START_ROUTINE) InstanceThread,
				    (LPVOID) hPipe,
				    0,
				    &dwThreadId);
	     if (hThread == NULL)
	       MyErrExit("CreateThread");
#endif
	  }
	else
	  {
//	     CloseHandle(hPipe);
	  }
//     }

   CloseHandle(hPipe);

   return 0;
}
Пример #2
0
BOOL CreateWorkers(HANDLE hCompletionPort)
{
    DWORD dwThread;
    HANDLE hThread;
    DWORD i;
    SYSTEM_INFO SystemInfo;

    GetSystemInfo(&SystemInfo);

    for (i = 0; i < 1; i++) {
        hThread = CreateThread(NULL, 0, WorkerThread, hCompletionPort, 0, &dwThread);
        if (!hThread) {
            MyErrExit("CreateThread WorkerThread");
            // Unreachable: return FALSE;
        }
        CloseHandle(hThread);
    }
    return TRUE;
}
Пример #3
0
 DWORD main(int argc, char *argv[]) { 
  HANDLE hPipe; 
  LPVOID lpvMessage; 
  CHAR chBuf[512]; 
  BOOL fSuccess; 
  DWORD cbRead, cbWritten, dwMode; 
  LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe"; 
 
  /* Try to open a named pipe; wait for it, if necessary. */ 
 
  while (1) { 
      hPipe = CreateFile( 
          lpszPipename,   /* pipe name           */ 
          GENERIC_READ |  /* read/write access   */ 
          GENERIC_WRITE, 

          0,              /* no sharing          */ 
          NULL,           /* no security attr.   */ 
          OPEN_EXISTING,  /* opens existing pipe */ 
          0,              /* default attributes  */ 
          NULL);          /* no template file    */ 
 
      /* Break if the pipe handle is valid. */ 
 
      if (hPipe != INVALID_HANDLE_VALUE) 
          break; 
 
      /* Exit if an error other than ERROR_PIPE_BUSY occurs. */ 
 
      if (GetLastError() != ERROR_PIPE_BUSY) 

          MyErrExit("Could not open pipe"); 
 
      /* All pipe instances are busy, so wait for 20 seconds. */ 
 
      if (! WaitNamedPipe(lpszPipename, 20000) ) 
          MyErrExit("Could not open pipe"); 
 
  } 
 
  /* The pipe connected; change to message-read mode. */ 
 
  dwMode = PIPE_READMODE_MESSAGE; 
  fSuccess = SetNamedPipeHandleState( 
      hPipe,    /* pipe handle          */ 
      &dwMode,  /* new pipe mode        */ 
      NULL,     /* don't set max. bytes */ 

      NULL);    /* don't set max. time  */ 
  if (! fSuccess) 
      MyErrExit("SetNamedPipeHandleState"); 
 
  /* Send a message to the pipe server. */ 
 
  lpvMessage = (argc > 1) ? argv[1] : "default message"; 
 
  fSuccess = WriteFile( 
      hPipe,                  /* pipe handle     */ 
      lpvMessage,             /* message         */ 
      strlen(lpvMessage) + 1, /* message length  */ 
      &cbWritten,             /* bytes written   */ 
      NULL);                  /* not overlapped  */ 

  if (! fSuccess) 
      MyErrExit("WriteFile"); 
 
  do { 
 
      /* Read from the pipe. */ 
 
      fSuccess = ReadFile( 
          hPipe,    /* pipe handle              */ 
          chBuf,    /* buffer to receive reply  */ 
          512,      /* size of buffer           */ 
          &cbRead,  /* number of bytes read     */ 
          NULL);    /* not overlapped           */ 
 
      if (! fSuccess && GetLastError() != ERROR_MORE_DATA) 
          break; 

 
      /* Reply from the pipe is written to STDOUT. */ 
 
      if (! WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), 
              chBuf, cbRead, &cbWritten, NULL)) 
          break; 
 
  } while (! fSuccess); /* repeat loop if ERROR_MORE_DATA */ 
 
  CloseHandle(hPipe); 
 
  return 0; 
 
} 
Пример #4
0
int main(void) 
{

    //printf("SHARE %d\n", *KMotionLocal.sharePtr);
    /* SJH - modified to listen to a TCP socket in addition to the unix domain (local) socket.
       Listens at port KMOTION_PORT (defined in KMotionDLL.h).
       FIXME: need to make this an argc/argv parameter.
    */
#ifdef _DEAMON
	//daemonize2();
	daemonize();
#endif
    //http://robertoacevedo.net/blog/2012/12/03/socket-server/
    pthread_attr_t attr; // Thread attribute
    pthread_attr_init(&attr); // Creating thread attributes
    pthread_attr_setschedpolicy(&attr, SCHED_FIFO); // FIFO scheduling for threads
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // Don't want threads (particualrly main)
                                                                   // waiting on each other

	openlog("KMotionServer", LOG_PID|LOG_CONS, LOG_USER);
	syslog(LOG_ERR, "KMotionServer started ");


    int tcp_socket;
    int main_socket;
    int client_socket;
    unsigned int t;
    struct sockaddr_un local, remote;
    struct sockaddr_in tlocal, tremote;
    fd_set rfds;
    int retval;
    socklen_t len;
    bool select_timedout;


    if ((main_socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
    	perrorExit("socket");
    }
    if ((tcp_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    	perrorExit("tcp socket");
    }

    if (strlen(SOCK_PATH) >= sizeof(local.sun_path)) {
    	perrorExit("path too long!");
    }

    local.sun_family = AF_UNIX;
    strcpy(local.sun_path, SOCK_PATH);

    int unlink_err;
    if((unlink_err = unlink(local.sun_path))){
    	logError("unlink");
    }

    //http://idletechnology.blogspot.se/2011/12/unix-domain-sockets-on-osx.html
#ifdef __APPLE__
    local.sun_len = sizeof(local);
    if (bind(main_socket, (struct sockaddr *)&local, SUN_LEN(&local)) == -1) {
#else
    len = strlen(local.sun_path) + sizeof(local.sun_family);
    if (bind(main_socket, (struct sockaddr *)&local, len) == -1) {
#endif
    	perrorExit("bind");
    }
    
    
    tlocal.sin_family = AF_INET;
    tlocal.sin_port = htons(KMOTION_PORT);
    tlocal.sin_addr.s_addr = INADDR_ANY;
    len = sizeof(tlocal);
    if (bind(tcp_socket, (struct sockaddr *)&tlocal, len) == -1) {
    	perrorExit("tcp bind");
    }
    

    if (listen(main_socket, 5) == -1) {
    	perrorExit("listen");
    }
    if (listen(tcp_socket, 5) == -1) {
    	perrorExit("tcp listen");
    }

   for (int i=0; i<MAX_BOARDS; i++) ConsolePipeHandle[i]=0;
 
// The main loop creates an instance of the named pipe and 
// then waits for a client to connect to it. When the client 
// connects, a thread is created to handle communications 
// with that client, and the loop is repeated. 
	//pthread_t ct = pthread_self();
	//printf("Thread %.8x %.8x: Current thread\n", ct);
   select_timedout = false;
   for (;;) 
   { 
       
       FD_ZERO(&rfds);
       FD_SET(main_socket, &rfds);
       FD_SET(tcp_socket, &rfds);

       if(!select_timedout){
         syslog(LOG_ERR,"Main Thread. Waiting for a connection...\n");
       }

       struct timeval timeout;
       // Initialize the timeout data structure.
       timeout.tv_sec = 1;
       timeout.tv_usec = 0;

       retval = select(tcp_socket+1, &rfds, NULL, NULL, &timeout);
       select_timedout = retval == 0;
       if (retval < 0){
          perrorExit("select");
       } else if(select_timedout){
         //If exit() is executed in the processs that started the server we never get here
         //Hence the reference counting from KMotionDLl.nInstances must be made.
         if (nClients <= 0) break;                // nobody left - terminate server
         if (KMotionDLL.nInstances() < 2) break;  // nobody left - terminate server
         continue; //timeout
       } else if (FD_ISSET(main_socket, &rfds)) {
            t = sizeof(remote);
            client_socket = accept(main_socket, (struct sockaddr *)&remote, &t);
       }
       else if (FD_ISSET(tcp_socket, &rfds)) {
            t = sizeof(tremote);
            client_socket = accept(tcp_socket, (struct sockaddr *)&tremote, &t);
            if (client_socket >= 0) {
                int flag = 1;
                setsockopt(client_socket, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
            }
       }
       else {
            // select() man page indicates possibility that there is nothing really there
            continue;
       }

       if (client_socket < 0) {
         perrorExit("Main Thread. accept");
       } else {
         //struct timeval tv;
         //tv.tv_sec = 5;  /* 30 Secs Timeout */
         //setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval));

         syslog(LOG_ERR,"Main Thread. Connected descriptor %d %s\n",
             client_socket, FD_ISSET(tcp_socket, &rfds) ? "(tcp)" : "(local)");
         nClients++;

         syslog(LOG_ERR,"Main Thread. Spawning worker\n");
         pthread_t thr;
         // initialize data to pass to thread
         thdata data;
         data.file_desc = client_socket;

         if(pthread_create(&thr, &attr, &InstanceThread, (void *) &data))
         {
            MyErrExit("Main Thread. pthread_create");
         }
       }

   }
   closelog();
   syslog(LOG_ERR,"Main Thread. Closing server\n");
   exit(EXIT_SUCCESS);
} 
//http://www.amparo.net/ce155/thread-ex.html
void * InstanceThread(void *ptr){
	thdata *data = (thdata*) ptr;
	int thread_socket = data->file_desc;
	//pthread_t ct = pthread_self();
	//printf("Thread %.8x %.8x: Current thread\n", ct);
	syslog(LOG_ERR,"The ID of this of this thread is: %ld\n", syscall(SYS_gettid/*224*/));

	syslog(LOG_ERR,"Worker Thread. Nr of Clients when entered %d", nClients);
	//vsyslog(LOG_INFO, "Inside Thread %d\n", thread_socket);
	syslog(LOG_ERR, "Worker Thread. Inside Thread %d\n", thread_socket);

	char chRequest[BUFSIZE];
	char chReply[BUFSIZE];
	unsigned short cbReplyBytes;
	int cbBytesRead, cbWritten;
	
	// SJH - messages to/from client must now be prefixed with 2-byte length word (except for ACK 0xAA from client
	// in response to console or error messages).  This allows working over
	// network with SOCK_STREAM sockets where message boundaries are likely to be broken.  Even with Unix 
	// domain sockets, this is safer.
	unsigned short   msglen;
	unsigned short   len;
	enum {
	    RD_LEN,
	    RD_MSG
	} state;

    state = RD_LEN;
    len = 0;
    msglen = sizeof(msglen);
    bool cont = true;

	while(cont) {

		cbBytesRead = recv(thread_socket, chRequest + len, msglen - len, 0);
		if (cbBytesRead <= 0) {
			if (cbBytesRead < 0){
				logError("Worker Thread. recv");
			} else {
				syslog(LOG_ERR,"Worker Thread. received 0 bytes");
			}
			break;
		}
		len += cbBytesRead;
		switch (state) 
		{
		case RD_LEN:
		    if (len == msglen) {
		        memcpy(&msglen, chRequest, sizeof(msglen));
		        state = RD_MSG;
		        len = 0;
		        if (msglen > sizeof(chRequest)) {  
		            // Too long to possibly fit in buffer.  This should not happen unless client bad.
				    syslog(LOG_ERR,"Worker Thread. Message prefix %hu too long", msglen);
				    cont = false;
				    continue;
		        }
		    }
		    continue;
		case RD_MSG:
		    if (len == msglen) {
		        cbBytesRead = len;
		        msglen = sizeof(msglen);
		        state = RD_LEN;
		        len = 0;
		        break;  // from switch and process this msg
		    }
		    continue;
		}

		GetAnswerToRequest(chRequest, cbBytesRead, chReply+sizeof(msglen), &cbReplyBytes, thread_socket);
		memcpy(chReply, &cbReplyBytes, sizeof(msglen));
		cbReplyBytes += sizeof(msglen);
		cbWritten = send(thread_socket, chReply, cbReplyBytes, 0);

		if (cbWritten < 0 || cbReplyBytes != cbWritten) {
			if (cbWritten < 0){
				logError("Worker Thread. send");
			} else {
				syslog(LOG_ERR,"Worker Thread. %d bytes written != %d bytes sent\n",cbWritten,cbReplyBytes);
			}
			break;
		}
		
	}
	syslog(LOG_ERR,"Worker Thread. Exiting thread %d", thread_socket);

	// Flush the pipe to allow the client to read the pipe's contents
	// before disconnecting. Then disconnect the pipe, and close the
	// handle to this pipe instance.

	//	   FlushFileBuffers(thread_socket);
	//	   DisconnectNamedPipe(thread_socket);
	//	   CloseHandle(thread_socket);
	if(shutdown(thread_socket,SHUT_RDWR)< 0){
		logError("thread socket shutdown");
	}

	close(thread_socket);
	syslog(LOG_ERR,"Worker Thread. Nr of clients left %d", --nClients);
	pthread_exit(0);
	return 0;
}
Пример #5
0
void perrorExit(const char *s)
{
	logError(s);
	MyErrExit(s);
}
Пример #6
0
DWORD main(int argc, char *argv[])
{
    HANDLE hPipe;
    SYELOG_MESSAGE Message;
    BOOL fSuccess;
    DWORD cbWritten, dwMode;

    // Try to open a named pipe; wait for it, if necessary.

    TIME_ZONE_INFORMATION tzi;
    GetTimeZoneInformation(&tzi);

    for (;;) {
        hPipe = CreateFileW(SYELOG_PIPE_NAMEW,  // pipe name
                            GENERIC_WRITE,      // write access only
                            0,                  // no sharing
                            NULL,               // no security attributes
                            OPEN_EXISTING,      // opens existing pipe
                            0,                  // default attributes
                            NULL);              // no template file

        // Break if the pipe handle is valid.
         if (hPipe != INVALID_HANDLE_VALUE)
            break;

        // Exit if an error other than ERROR_PIPE_BUSY occurs.

        if (GetLastError() != ERROR_PIPE_BUSY)
            MyErrExit("Could not open pipe");

        // All pipe instances are busy, so wait for 1 seconds.

        if (!WaitNamedPipeW(SYELOG_PIPE_NAMEW, 1000))
            MyErrExit("Could not open pipe");
    }

    // The pipe connected; change to message-read mode.
    dwMode = PIPE_READMODE_MESSAGE;
    fSuccess = SetNamedPipeHandleState(hPipe,    // pipe handle
                                       &dwMode,  // new pipe mode
                                       NULL,     // don't set maximum bytes
                                       NULL);    // don't set maximum time
    if (!fSuccess)
        MyErrExit("SetNamedPipeHandleState");

    // Send a message to the pipe server.

    memset(&Message, 0, sizeof(Message));

    StringCchCopyA(Message.szMessage, ARRAYSIZE(Message.szMessage),
                   (argc > 1) ? argv[1] : "sltestp: hello world!");

    Message.nFacility = SYELOG_FACILITY_APPLICATION;
    Message.nSeverity = SYELOG_SEVERITY_INFORMATION;
    Message.nProcessId = GetCurrentProcessId();
    GetSystemTimeAsFileTime(&Message.ftOccurance);
    PCSTR pszEnd = Message.szMessage;
    for (; *pszEnd; pszEnd++) {
        // no internal contents.
    }
    Message.nBytes = (USHORT)(pszEnd - ((PCSTR)&Message) + 1);

    fSuccess = WriteFile(hPipe,                  // pipe handle
                         &Message,             // message
                         Message.nBytes, // message length
                         &cbWritten,             // bytes written
                         NULL);                  // not overlapped
    if (! fSuccess)
        MyErrExit("WriteFile");

    CloseHandle(hPipe);

    GetTimeZoneInformation(&tzi);

    return 0;
}
Пример #7
0
DWORD main(int argc, char **argv)
{
    HANDLE hCompletionPort;
    BOOL fNeedHelp = FALSE;
    WCHAR wzzDrop[1024] = L"build\0nmake\0";

    GetSystemTimeAsFileTime((FILETIME *)&s_llStartTime);
    StringCchPrintfA(s_szPipe, ARRAYSIZE(s_szPipe), "%s.%d", TBLOG_PIPE_NAME, GetCurrentProcessId());

    int arg = 1;
    for (; arg < argc && (argv[arg][0] == '-' || argv[arg][0] == '/'); arg++) {
        CHAR *argn = argv[arg] + 1;
        CHAR *argp = argn;
        while (*argp && *argp != ':' && *argp != '=') {
            argp++;
        }
        if (*argp == ':' || *argp == '=') {
            *argp++ = '\0';
        }

        switch (argn[0]) {

          case 'd':                                     // Drop Processes
          case 'D':
            if (*argp) {
                PWCHAR pwz = wzzDrop;
                while (*argp) {
                    if (*argp == ';') {
                        *pwz++ = '\0';
                    }
                    else {
                        *pwz++ = *argp++;
                    }
                }
                *pwz++ = '\0';
                *pwz = '\0';
            }
          case 'o':                                 // Output file.
          case 'O':
            StringCchCopyA(s_szLogFile, ARRAYSIZE(s_szLogFile), argp);
            break;

          case 'v':                                     // Verbose
          case 'V':
            s_fVerbose = TRUE;
            break;

          case '?':                                 // Help.
            fNeedHelp = TRUE;
            break;

          default:
            fNeedHelp = TRUE;
            printf("TRACEBLD: Bad argument: %s:%s\n", argn, argp);
            break;
        }
    }

    if (arg >= argc) {
        fNeedHelp = TRUE;
    }

    if (fNeedHelp) {
        printf("Usage:\n"
               "    tracebld [options] command {command arguments}\n"
               "Options:\n"
               "    /o:file    Log all events to the output files.\n"
               "    /?         Display this help message.\n"
               "Summary:\n"
               "    Runs the build commands and figures out which files have dependencies..\n"
               "\n");
        exit(9001);
    }

    // Create the completion port.
    hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 0);
    if (hCompletionPort == NULL) {
        MyErrExit("CreateIoCompletionPort");
    }

    // Create completion port worker threads.
    //
    CreateWorkers(hCompletionPort);
    CreatePipeConnection(hCompletionPort, 0);

    printf("TRACEBLD: Ready for clients.  Press Ctrl-C to stop.\n");

    /////////////////////////////////////////////////////////// Validate DLLs.
    //
    CHAR szTmpPath[MAX_PATH];
    CHAR szExePath[MAX_PATH];
    CHAR szDllPath[MAX_PATH];
    PCHAR pszFilePart = NULL;

    if (!GetModuleFileNameA(NULL, szTmpPath, ARRAYSIZE(szTmpPath))) {
        printf("TRACEBLD: Couldn't retreive exe name.\n");
        return 9002;
    }
    if (!GetFullPathNameA(szTmpPath, ARRAYSIZE(szExePath), szExePath, &pszFilePart) ||
        pszFilePart == NULL) {
        printf("TRACEBLD: Error: %s is not a valid path name..\n", szTmpPath);
        return 9002;
    }

    StringCchCopyA(pszFilePart, szExePath + ARRAYSIZE(szExePath) - pszFilePart,
             "trcbld" DETOURS_STRINGIFY(DETOURS_BITS) ".dll");
    StringCchCopyA(szDllPath, ARRAYSIZE(szDllPath), szExePath);

    //////////////////////////////////////////////////////////////////////////
    STARTUPINFOA si;
    PROCESS_INFORMATION pi;
    CHAR szCommand[2048];
    CHAR szExe[MAX_PATH];
    CHAR szFullExe[MAX_PATH] = "\0";
    PCHAR pszFileExe = NULL;

    ZeroMemory(&si, sizeof(si));
    ZeroMemory(&pi, sizeof(pi));
    si.cb = sizeof(si);

    szCommand[0] = L'\0';

    StringCchCopyA(szExe, sizeof(szExe), argv[arg]);
    for (; arg < argc; arg++) {
        if (strchr(argv[arg], ' ') != NULL || strchr(argv[arg], '\t') != NULL) {
            StringCchCatA(szCommand, sizeof(szCommand), "\"");
            StringCchCatA(szCommand, sizeof(szCommand), argv[arg]);
            StringCchCatA(szCommand, sizeof(szCommand), "\"");
        }
        else {
            StringCchCatA(szCommand, sizeof(szCommand), argv[arg]);
        }

        if (arg + 1 < argc) {
            StringCchCatA(szCommand, sizeof(szCommand), " ");
        }
    }
    printf("TRACEBLD: Starting: `%s'\n", szCommand);
    printf("TRACEBLD:   with `%s'\n", szDllPath);
    fflush(stdout);

    DWORD dwFlags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED;

    SetLastError(0);
    SearchPathA(NULL, szExe, ".exe", ARRAYSIZE(szFullExe), szFullExe, &pszFileExe);


    if (!DetourCreateProcessWithDllExA(szFullExe[0] ? szFullExe : NULL, szCommand,
                                       NULL, NULL, TRUE, dwFlags, NULL, NULL,
                                       &si, &pi, szDllPath, NULL)) {
        printf("TRACEBLD: DetourCreateProcessWithDllEx failed: %d\n", GetLastError());
        ExitProcess(9007);
    }

    ZeroMemory(&s_Payload, sizeof(s_Payload));
    s_Payload.nParentProcessId = GetCurrentProcessId();
    s_Payload.nTraceProcessId = GetCurrentProcessId();
    s_Payload.nGeneology = 1;
    s_Payload.rGeneology[0] = 0;
    StringCchCopyW(s_Payload.wzStdin, ARRAYSIZE(s_Payload.wzStdin), L"\\\\.\\CONIN$");
    StringCchCopyW(s_Payload.wzStdout, ARRAYSIZE(s_Payload.wzStdout), L"\\\\.\\CONOUT$");
    StringCchCopyW(s_Payload.wzStderr, ARRAYSIZE(s_Payload.wzStderr), L"\\\\.\\CONOUT$");
    StringCchCopyW(s_Payload.wzParents, ARRAYSIZE(s_Payload.wzParents), L"");
    CopyEnvironment(s_Payload.wzzDrop, wzzDrop);
    LPWCH pwStrings = GetEnvironmentStringsW();
    CopyEnvironment(s_Payload.wzzEnvironment, pwStrings);
    FreeEnvironmentStringsW(pwStrings);

    if (!DetourCopyPayloadToProcess(pi.hProcess, s_guidTrace,
                                    &s_Payload, sizeof(s_Payload))) {
        printf("TRACEBLD: DetourCopyPayloadToProcess failed: %d\n", GetLastError());
        ExitProcess(9008);
    }

    ResumeThread(pi.hThread);

    WaitForSingleObject(pi.hProcess, INFINITE);

    DWORD dwResult = 0;
    if (!GetExitCodeProcess(pi.hProcess, &dwResult)) {
        printf("TRACEBLD: GetExitCodeProcess failed: %d\n", GetLastError());
        return 9008;
    }

    printf("TRACEBLD: %d processes.\n", s_nTotalClients);

    return dwResult;
}
Пример #8
0
// Creates a pipe instance and initiate an accept request.
//
PCLIENT CreatePipeConnection(HANDLE hCompletionPort, LONG nClient)
{
    HANDLE hPipe = CreateNamedPipeA(s_szPipe,                   // pipe name
                                    PIPE_ACCESS_INBOUND |       // read-only 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,   // unlimited instances
                                    0,                          // output buffer size
                                    0,                          // input buffer size
                                    20000,                      // client time-out
                                    NULL);                      // no security attributes
    if (hPipe == INVALID_HANDLE_VALUE) {
        MyErrExit("CreateNamedPipe");
    }

    // Allocate the client data structure.
    //
    PCLIENT pClient = (PCLIENT) GlobalAlloc(GPTR, sizeof(CLIENT));
    if (pClient == NULL) {
        MyErrExit("GlobalAlloc pClient");
    }

    CHAR szLogFile[MAX_PATH];
    StringCchPrintfA(szLogFile, ARRAYSIZE(szLogFile), "%s.%08d.xml", s_szLogFile, nClient);

    ZeroMemory(pClient, sizeof(*pClient));
    pClient->hPipe = hPipe;
    pClient->nClient = nClient;
    pClient->fAwaitingAccept = TRUE;
    pClient->hFile = CreateFileA(szLogFile,
                                 GENERIC_WRITE,
                                 FILE_SHARE_READ,
                                 NULL,
                                 CREATE_ALWAYS,
                                 FILE_ATTRIBUTE_NORMAL |
                                 FILE_FLAG_SEQUENTIAL_SCAN,
                                 NULL);
    if (pClient->hFile == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "TRACEBLD: Error opening output file: %s: %d\n\n",
                szLogFile, GetLastError());
        fflush(stderr);
        MyErrExit("CreateFile");
    }

    // Associate file with our complietion port.
    //
    if (!CreateIoCompletionPort(pClient->hPipe, hCompletionPort, (ULONG_PTR)pClient, 0)) {
        MyErrExit("CreateIoComplietionPort pClient");
    }

    if (!ConnectNamedPipe(hPipe, pClient)) {
        DWORD error = GetLastError();

        if (error == ERROR_IO_PENDING) {
            return NULL;
        }
        if (error == ERROR_PIPE_CONNECTED) {
#if 0
            pClient->LogMessageV("<!-- ConnectNamedPipe client already connected. -->");
#endif
            pClient->fAwaitingAccept = FALSE;
        }
        else if (error != ERROR_IO_PENDING &&
                 error != ERROR_PIPE_LISTENING) {

            MyErrExit("ConnectNamedPipe");
        }
    }
    else {
        fprintf(stderr, "*** ConnectNamedPipe accepted immediately.\n");
#if 0
        pClient->LogMessageV("<!-- ConnectNamedPipe accepted immediately. -->");
#endif
        pClient->fAwaitingAccept = FALSE;
    }
    return pClient;
}