void CSerialPort::ClosePort()
{
	if (m_hThreadComm != INVALID_HANDLE_VALUE) {
		SetEvent(m_hShutdownEvent);
		WaitForSingleObject(m_hThreadComm, INFINITE);
		WaitForSingleObject(m_hThreadSend, INFINITE);
		CLOSEHANDLE(m_hThreadComm);
		CLOSEHANDLE(m_hThreadSend);
	}


	if (m_hComm != INVALID_HANDLE_VALUE) {
		CloseHandle(m_hComm);
		m_hComm = INVALID_HANDLE_VALUE;
	}

	if (m_hShutdownEvent != INVALID_HANDLE_VALUE)
		ResetEvent(m_hShutdownEvent);

	if (m_ov.hEvent != INVALID_HANDLE_VALUE)
		ResetEvent(m_ov.hEvent);

	if (m_hWriteEvent != INVALID_HANDLE_VALUE)
		ResetEvent(m_hWriteEvent);
}
BOOL CAlarmCenterApp::IfProcessRunning()
{
	m_hMutex = CreateMutex(nullptr, FALSE, MUTEX_NAME);
	if (GetLastError() == ERROR_ALREADY_EXISTS) {
		CLOSEHANDLE(m_hMutex);
		return TRUE;
	} else {
		return FALSE;
	}
}
void CClientManager::Stop()
{
	AUTO_LOG_FUNCTION;
	m_bShuttingDown = TRUE;

	if (INVALID_HANDLE_VALUE != m_hEventShutdown) {
		SetEvent(m_hEventShutdown);
	}

	if (INVALID_HANDLE_VALUE != m_hThreadRecv) {
		WaitForSingleObject(m_hThreadRecv, INFINITE);
		CLOSEHANDLE(m_hThreadRecv);
	}
	
	if (INVALID_HANDLE_VALUE != m_hThreadConn) {
		WaitForSingleObject(m_hThreadConn, INFINITE);
		CLOSEHANDLE(m_hThreadConn);
	}

	CLOSEHANDLE(m_hEventShutdown);

	m_client_map.clear();
}
int CAlarmCenterApp::ExitInstance()
{
	ControlBarCleanUp();
	CLOSEHANDLE(m_hMutex);
	//CefShutdown();
	WSACleanup();
	CWinApp::ExitInstance();

	CAppResource::release_singleton();
	util::CConfigHelper::release_singleton();
	core::user_manager::release_singleton();
	res::release_singleton();

	return exit_code_;
}
//
// Delete dynamic memory
//
CSerialPort::~CSerialPort()
{
	if (m_hThreadComm != INVALID_HANDLE_VALUE) {
		SetEvent(m_hShutdownEvent);
		WaitForSingleObject(m_hThreadComm, INFINITE);
		WaitForSingleObject(m_hThreadSend, INFINITE);
		CLOSEHANDLE(m_hThreadComm);
		CLOSEHANDLE(m_hThreadSend);
	}
	CLOSEHANDLE(m_hEventSent);
	CLOSEHANDLE(m_hShutdownEvent);
	CLOSEHANDLE(m_hComm);
	CLOSEHANDLE(m_hWriteEvent);
	CLOSEHANDLE(m_ov.hEvent);
	DeleteCriticalSection(&m_csCommunicationSync);
	//JLOG(_T("CSerialPort::Thread ended\n"));
	SAFEDELETEARR(m_dataWriteBuffer);
}
Exemple #6
0
int
verifyEAuth_(struct lsfAuth *auth, struct sockaddr_in *from)
{
    static char fname[] = "verifyEAuth/lib.eauth.c";
    char path[MAXPATHLEN], uData[256], ok;
    char *eauth_client, *eauth_server, *eauth_aux_data, *eauth_aux_status;
    int cc, i;
    static int connected = FALSE;
    static int in[2], out[2];

    if (logclass & LC_TRACE)
        ls_syslog(LOG_DEBUG, "%s ...", fname);

    if (!(genParams_[LSF_AUTH].paramValue &&
          !strcmp(genParams_[LSF_AUTH].paramValue, AUTH_PARAM_EAUTH)))
        return -1;

    eauth_client = getenv("LSF_EAUTH_CLIENT");
    eauth_server = getenv("LSF_EAUTH_SERVER");
    eauth_aux_data = getenv("LSF_EAUTH_AUX_DATA");
    eauth_aux_status = getenv("LSF_EAUTH_AUX_STATUS");

    sprintf(uData, "%d %d %s %s %d %d %s %s %s %s\n", auth->uid, auth->gid,
            auth->lsfUserName, inet_ntoa(from->sin_addr),
            (int) ntohs(from->sin_port), auth->k.eauth.len,
            (eauth_client ? eauth_client : "NULL"),
            (eauth_server ? eauth_server : "NULL"),
            (eauth_aux_data ? eauth_aux_data : "NULL"),
            (eauth_aux_status ? eauth_aux_status : "NULL"));

    memset(path,0,sizeof(path));
    ls_strcat(path,sizeof(path),genParams_[LSF_SERVERDIR].paramValue);
    ls_strcat(path,sizeof(path),"/");
    ls_strcat(path,sizeof(path),EAUTHNAME);

    if (logclass & (LC_AUTH | LC_TRACE))
        ls_syslog(LOG_DEBUG, "%s: <%s> path <%s> connected=%d", fname, uData,
                  path, connected);

    if (connected) {
        struct timeval tv;
        fd_set  mask;

        FD_ZERO(&mask);
        FD_SET(out[0], &mask);

        tv.tv_sec = 0;
        tv.tv_usec = 0;

        if ((cc = select(out[0] + 1, &mask, NULL, NULL, &tv)) > 0) {
            if (logclass & (LC_AUTH | LC_TRACE))
                ls_syslog(LOG_DEBUG, "%s: <%s> got exception",
                          fname, uData);
            connected = FALSE;
            close(in[1]);
            close(out[0]);
        } else {
            if (cc < 0)
                ls_syslog(LOG_ERR, I18N_FUNC_S_FAIL_M, fname, "select", uData);
        }

        if (logclass & (LC_AUTH | LC_TRACE))
            ls_syslog(LOG_DEBUG, "%s: <%s> select returned cc=%d", fname,
                      uData, cc);

    }

    if (!connected) {

        int pid;
        char *user;

        {
            if ((user = getLSFAdmin()) == NULL) {
                return -1;
            }
        }

        if (pipe(in) < 0) {
            ls_syslog(LOG_ERR, I18N_FUNC_S_FAIL_M, fname, "pipe(in)", uData);
            lserrno = LSE_SOCK_SYS;
            return -1;
        }

        if (pipe(out) < 0) {
            ls_syslog(LOG_ERR, I18N_FUNC_S_FAIL_M, fname, "pipe(out)", uData);
            lserrno = LSE_SOCK_SYS;
            return -1;
        }


        if ((pid = fork()) == 0) {
            char *myargv[3];
            struct passwd *pw;

            if ((pw = getpwnam(user)) == (struct passwd *)NULL) {
                ls_syslog(LOG_ERR, I18N_FUNC_S_FAIL_M, fname, "getpwnam", user);
                exit(-1);
            }

            if (setuid(pw->pw_uid) < 0) {
                ls_syslog(LOG_ERR, I18N_FUNC_D_FAIL_M, fname, "setuid", (int)pw->pw_uid);
                exit(-1);
            }

            for (i = 1; i < NSIG; i++)
                Signal_(i, SIG_DFL);

            alarm(0);

            close(in[1]);
            if (dup2(in[0], 0) == -1) {
                ls_syslog(LOG_ERR, I18N_FUNC_S_FAIL_M, fname, "dup2(in[0])", uData);
            }

            close(out[0]);
            if (dup2(out[1], 1) == -1) {
                ls_syslog(LOG_ERR, I18N_FUNC_S_FAIL_M, fname, "dup2(out[1])", uData);
            }

            for (i = 3; i < sysconf(_SC_OPEN_MAX); i++)
                close(i);

            myargv[0] = path;
            myargv[1] = "-s";
            myargv[2] = NULL;

            execvp(myargv[0], myargv);
            ls_syslog(LOG_ERR, I18N_FUNC_S_FAIL_M, fname, "execvp", myargv[0]);
            exit(-1);
        }

        close(in[0]);
        close(out[1]);

        if (pid == -1) {
            ls_syslog(LOG_ERR, I18N_FUNC_S_FAIL_M, fname, "fork", path);
            close(in[1]);
            close(out[0]);
            lserrno = LSE_FORK;
            return -1;
        }

        connected = TRUE;
    }

    i = strlen(uData);

    if ((cc = b_write_fix(in[1], uData, i)) != i) {
        ls_syslog(LOG_ERR, _i18n_msg_get(ls_catd , NL_SETN, 5513,
                                         "%s: b_write_fix <%s> failed, cc=%d, i=%d: %m"), /* catgets 5513 */
                  fname, uData, cc, i);
        CLOSEHANDLE(in[1]);
        CLOSEHANDLE(out[0]);
        connected = FALSE;
        return -1;
    }
    if(logclass & (LC_AUTH | LC_TRACE))
        ls_syslog(LOG_DEBUG, _i18n_msg_get(ls_catd , NL_SETN, 5514,
                                           "%s: b_write_fix <%s> ok, cc=%d, i=%d"),
                  fname, uData, cc, i);

    if ((cc = b_write_fix(in[1], auth->k.eauth.data, auth->k.eauth.len))
        != auth->k.eauth.len) {
        ls_syslog(LOG_ERR, _i18n_msg_get(ls_catd , NL_SETN, 5515,
                                         "%s: b_write_fix <%s> failed, eauth.len=%d, cc=%d"), /* catgets 5515 */
                  fname, uData, auth->k.eauth.len, cc);
        CLOSEHANDLE(in[1]);
        CLOSEHANDLE(out[0]);
        connected = FALSE;
        return -1;
    }
    if(logclass & (LC_AUTH | LC_TRACE))
        ls_syslog(LOG_DEBUG, _i18n_msg_get(ls_catd , NL_SETN, 5516,
                                           "%s: b_write_fix <%s> ok, eauth.len=%d, eauth.data=%.*s cc=%d:"),
                  fname, uData, auth->k.eauth.len,
                  auth->k.eauth.len, auth->k.eauth.data,cc);

    if ((cc = b_read_fix(out[0], &ok, 1)) != 1) {
        ls_syslog(LOG_ERR, _i18n_msg_get(ls_catd , NL_SETN, 5517,
                                         "%s: b_read_fix <%s> failed, cc=%d: %m"), /* catgets 5517 */
                  fname, uData, cc);
        CLOSEHANDLE(in[1]);
        CLOSEHANDLE(out[0]);
        connected = FALSE;
        return -1;
    }

    if (ok != '1') {
        ls_syslog(LOG_ERR, _i18n_msg_get(ls_catd , NL_SETN, 5518,
                                         "%s: eauth <%s> len=%d failed, rc=%c"), /* catgets 5518 */
                  fname, uData, auth->k.eauth.len, ok);
        return -1;
    }

    return 0;
}
//
// Initialize the port. This can be port 1 to 4.
//
BOOL CSerialPort::InitPort(CWnd* pPortOwner,	// the owner (CWnd) of the port (receives message)
						   UINT  portnr,		// portnumber (1..4)
						   UINT  baud,			// baudrate
						   char  parity,		// parity 
						   UINT  databits,		// databits 
						   UINT  stopbits,		// stopbits 
						   DWORD dwCommEvents,	// EV_RXCHAR, EV_CTS etc
						   UINT  writebuffersize)	// size to the writebuffer
{
	assert(portnr > 0 && portnr < 5);
	//assert(pPortOwner != NULL);

	// if the thread is alive: Kill
	if (m_hThreadComm != INVALID_HANDLE_VALUE) {
		SetEvent(m_hShutdownEvent);
		WaitForSingleObject(m_hThreadComm, INFINITE);
		WaitForSingleObject(m_hThreadSend, INFINITE);
		CLOSEHANDLE(m_hThreadComm);
		CLOSEHANDLE(m_hThreadSend);
	}

	// create events
	if (m_ov.hEvent != INVALID_HANDLE_VALUE)
		ResetEvent(m_ov.hEvent);
	m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	if (m_hWriteEvent != INVALID_HANDLE_VALUE)
		ResetEvent(m_hWriteEvent);
	m_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	if (m_hShutdownEvent != INVALID_HANDLE_VALUE)
		ResetEvent(m_hShutdownEvent);
	m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	// initialize the event objects
	m_hEventArray[0] = m_hShutdownEvent;	// highest priority
	m_hEventArray[1] = m_ov.hEvent;
	m_hEventArray[2] = m_hWriteEvent;

	// initialize critical section
	InitializeCriticalSection(&m_csCommunicationSync);

	// set buffersize for writing and save the owner
	m_pOwner = pPortOwner;

	if (m_dataWriteBuffer != NULL)
		delete[] m_dataWriteBuffer;
	m_dataWriteBuffer = new char[writebuffersize];

	m_nPortNr = portnr;

	m_nWriteBufferSize = writebuffersize;
	m_dwCommEvents = dwCommEvents;

	TCHAR szPort[128] = { 0 };
	TCHAR szBaud[128] = { 0 };

	// now it critical!
	EnterCriticalSection(&m_csCommunicationSync);

	// if the port is already opened: close it
	if (m_hComm != INVALID_HANDLE_VALUE) {
		CloseHandle(m_hComm);
		m_hComm = INVALID_HANDLE_VALUE;
	}

	// prepare port strings
	_stprintf_s(szPort, _T("COM%d"), portnr);
	_stprintf_s(szBaud, _T("baud=%d parity=%c data=%d stop=%d"),
				baud, parity, databits, stopbits);

	// get a handle to the port
	m_hComm = CreateFile(szPort,						// communication port string (COMX)
						 GENERIC_READ | GENERIC_WRITE,	// read/write types
						 0,								// comm devices must be opened with exclusive access
						 NULL,							// no security attributes
						 OPEN_EXISTING,					// comm devices must use OPEN_EXISTING
						 FILE_FLAG_OVERLAPPED,			// Async I/O
						 0);							// template must be 0 for comm devices

	if (m_hComm == INVALID_HANDLE_VALUE) {
		// port not found
		return FALSE;
	}

	// set the timeout values
	m_CommTimeouts.ReadIntervalTimeout = 1000;
	m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;
	m_CommTimeouts.ReadTotalTimeoutConstant = 1000;
	m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;
	m_CommTimeouts.WriteTotalTimeoutConstant = 1000;

	// configure
	if (SetCommTimeouts(m_hComm, &m_CommTimeouts)) {
		if (SetCommMask(m_hComm, dwCommEvents)) {
			if (GetCommState(m_hComm, &m_dcb)) {
				m_dcb.fRtsControl = RTS_CONTROL_ENABLE;		// set RTS bit high!
				if (BuildCommDCB(szBaud, &m_dcb)) {
					if (SetCommState(m_hComm, &m_dcb))
						; // normal operation... continue
					else
						ProcessErrorMessage("SetCommState()");
				} else
					ProcessErrorMessage("BuildCommDCB()");
			} else
				ProcessErrorMessage("GetCommState()");
		} else
			ProcessErrorMessage("SetCommMask()");
	} else
		ProcessErrorMessage("SetCommTimeouts()");

	// flush the port
	PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

	// release critical section
	LeaveCriticalSection(&m_csCommunicationSync);

	//JLOG(_T("Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n"), portnr);

	return TRUE;
}
//--------------------------------------------------------------------------//
//                                                                          //
//--------------------------------------------------------------------------//
BOOL StartHttpService(int argc, char *argv[])
{
    HANDLE hEventLog = NULL;
    BOOL bReturn = FALSE;
    char szReconfigEvent[MAX_PATH];
    char szDoneEvent[MAX_PATH];
    PRStatus webserver_run_status = PR_SUCCESS;

    // Process the argv and extract config_root into unique_name. 
    // Use this to name events.

    int c;
    char *serverconfig = NULL;
    while ((c = getopt(argc, argv, "s:n:d:r:f:cvi")) != -1) {
        switch(c) {
        case 'd':
            serverconfig = optarg;
            break;
        default:
            break;
        }
    }
    if (!serverconfig || !serverconfig[0])
        goto cleanup;

    // canonicalize the server config dir path in case it is a relative
    // path and use it to generate a unique id that is used for all server
    // to watchdog communication
    serverconfig = file_canonicalize_path(serverconfig);
    unique_name = set_uniquename(serverconfig);
    FREE(serverconfig);

    hEventLog = InitializeLogging(unique_name);

    wsprintf(szDoneEvent, "NS_%s", unique_name);

    phEvents[WS_SHUTDOWN] = OpenEvent(EVENT_ALL_ACCESS, FALSE, szDoneEvent);
    if (phEvents[WS_SHUTDOWN] != NULL)
    {
        // should not exist
        goto cleanup;
    }

    phEvents[WS_SHUTDOWN] = CreateEvent(NULL, TRUE, FALSE, szDoneEvent);
    if (phEvents[WS_SHUTDOWN] == NULL)
	goto cleanup;

    wsprintf(szReconfigEvent, "NR_%s", unique_name);

    phEvents[WS_RECONFIG] = OpenEvent(EVENT_ALL_ACCESS, FALSE, szReconfigEvent);
    if (phEvents[WS_RECONFIG] != NULL)
    {
        // should not exist
        goto cleanup;
    }

    phEvents[WS_RECONFIG] = CreateEvent(NULL, TRUE, FALSE, szReconfigEvent);
    if (phEvents[WS_RECONFIG] == NULL)
	goto cleanup;

    if (WebServer::Init(argc, argv) == PR_FAILURE)
        goto cleanup;

    MainThread = PR_CreateThread(PR_USER_THREAD,
				 webserver_run,
				 &webserver_run_status,
				 PR_PRIORITY_NORMAL,
				 PR_GLOBAL_THREAD,
				 PR_UNJOINABLE_THREAD,
				 65536);
    if (MainThread == NULL)
	goto cleanup;

    PRThread *thread;
			
    /* In NSPR20, the first thread becomes a user thread.
     * You can't go to sleep on a blocking call like WaitForSingleObject
     * or you'll kill the whole process.
     * So send it off to a native thread before Wait()ing.
     */
    thread = PR_CreateThread(PR_USER_THREAD,
				_WaitSignalThread,
				NULL,
				PR_PRIORITY_NORMAL,
				PR_GLOBAL_THREAD,
				PR_JOINABLE_THREAD,
				0);
			
    if (thread == NULL)
	goto cleanup;

    // the MainThread runs the server at this point, while we wait for
    // the WaitSignalThread to end

    PR_JoinThread(thread);

    if (webserver_run_status == PR_SUCCESS) {
        SuspendHttpdService();
        bReturn = TRUE;
    }
	
cleanup:
    if(!bReturn)
        LogErrorEvent(NULL, EVENTLOG_ERROR_TYPE, 0, MSG_BAD_STARTUP, "Initialization Failed", "");

    WebServer::Cleanup();

    TerminateLogging(hEventLog);

    if (phEvents[WS_SHUTDOWN])
        CLOSEHANDLE(phEvents[WS_SHUTDOWN]);

    if (phEvents[WS_RECONFIG])
        CLOSEHANDLE(phEvents[WS_RECONFIG]);

    return bReturn;
}
Exemple #9
0
/* ss_sendfiles:
   Send a response naming the data pipe, collect further names
   from further client messages, all according to the protocol above.
   Start the data pipe and arrange that all the files are sent
   by getting them all enqueued on the first queue.
   Destroy PackQueue at the end.  Arrange for the other queues
   to be destroyed by the usual Queue mechanism, or destroy them
   explicitly if they never get started.
*/
BOOL
ss_sendfiles(HANDLE hPipe, long lVersion)
{       /* Create the queues and set about filling the first one */

        QUEUE PackQueue, ReadQueue, SendQueue;

#ifdef SOCKETS
        SOCKET hpSend;
        static BOOL SocketsInitialized = FALSE;
#else
        HANDLE hpSend;          /* the data pipe */
#endif /* SOCKETS */

        char PipeName[80];      /* The name of the new data pipe */
        BOOL Started = FALSE;   /* TRUE if something enqueued */


#ifdef SOCKETS
        if( !SocketsInitialized )
        {
                WSADATA WSAData;

                if( ( WSAStartup( MAKEWORD( 1, 1 ), &WSAData ) ) == 0 )
                {
                        SocketsInitialized = TRUE;
                }
                else
                {
                        printf("WSAStartup failed");
                }
        }
#endif

        {
                /****************************************
                We need security attributes for the pipe to let anyone other than the
                current user log on to it.
                ***************************************/

                /* Allocate DWORDs for the ACL to get them aligned.  Round up to next DWORD above */
                DWORD Acl[(sizeof(ACL)+sizeof(ACCESS_ALLOWED_ACE)+3)/4+4];    // + 4 by experiment!!
                SECURITY_DESCRIPTOR sd;
                PSECURITY_DESCRIPTOR psd = &sd;
                PSID psid;
                SID_IDENTIFIER_AUTHORITY SidWorld = SECURITY_WORLD_SID_AUTHORITY;
                PACL pacl = (PACL)(&(Acl[0]));
                SECURITY_ATTRIBUTES sa;
                BOOL brc;
                DWORD lasterr;

                if (!AllocateAndInitializeSid( &SidWorld, 1, SECURITY_WORLD_RID
                                              , 1, 2, 3, 4, 5, 6, 7
                                              , &psid
                                              )
                   ) {
                        Error("AllocateAndInitializeSid");
                        return FALSE;
                   }

                if (!InitializeAcl(pacl, sizeof(Acl), ACL_REVISION)){
                        Error("InitializeAcl");
                        return FALSE;
                }
                if (!AddAccessAllowedAce(pacl, ACL_REVISION, GENERIC_WRITE|GENERIC_READ, psid)){
                        Error("AddAccessAllowedAce");
                        return FALSE;
                }
                if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION)){
                        Error("InitializeSecurityDescriptor");
                        return FALSE;
                }
                if (!SetSecurityDescriptorDacl(psd, TRUE, pacl, FALSE)){
                        Error("SetSecurityDescriptorDacl");
                        return FALSE;
                }
                sa.nLength = sizeof(sa);
                sa.lpSecurityDescriptor = psd;
                sa.bInheritHandle = TRUE;

                /* We now have a good security descriptor!  */

                /* Create the (new, unique) name of the pipe and then create the pipe */

                /* I am finding it hard to decide whether the following line (++PpipeCount)
                   actually needs a critical section or not.  The worst that could happen
                   would be that we got an attempt to create a pipe with an existing name.
                */
                ++PipeCount;
                sprintf(PipeName, "\\\\.\\pipe\\%s%d", PIPEPREFIX, PipeCount);

#ifdef SOCKETS
                if (!ss_sendnewresp( hPipe, SS_VERSION, SSRESP_PIPENAME
                                   , 0, 0, 0, TCPPORT, "")) {
                        dprintf1(( "Failed to send response on pipe %x naming new pipe.\n"
                              , hPipe));
                        return FALSE;           /* Caller will close hPipe */
                }

                if( !SocketListen( TCPPORT, &hpSend ) )
                {
                    dprintf1(("Could not create socket\n"));
                    return FALSE;
                }

                FreeSid(psid);
#else
                hpSend = CreateNamedPipe(PipeName,              /* pipe name */
                                PIPE_ACCESS_DUPLEX,     /* both read and write */
                                PIPE_WAIT|PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE,
                                1,              /* at most one instance */
                                10000,          /* sizeof(SSNEWPACK) + some for luck */
                                0,              /* dynamic inbound buffer allocation */
                                5000,           /* def. timeout 5 seconds */
                                &sa             /* security descriptor */
                                );
                FreeSid(psid);

                if (hpSend == INVALID_HANDLE_VALUE) {
                        dprintf1(("Could not create named data pipe\n"));
                        return FALSE;
                }
                dprintf1(("Data pipe %x called '%s' created for main pipe %x.\n", hpSend, PipeName, hPipe));

#endif /* SOCKETS */

        }




        /* Send the response which names the data pipe */

#ifndef SOCKETS
        if (!ss_sendnewresp( hPipe, SS_VERSION, SSRESP_PIPENAME
                           , 0, 0, 0, 0, PipeName)) {
                dprintf1(( "Failed to send response on pipe %x naming new pipe.\n"
                      , hPipe));
                CLOSEHANDLE(hpSend);
                return FALSE;           /* Caller will close hPipe */
        }

        if (!ConnectNamedPipe(hpSend, NULL)) {
                CLOSEHANDLE(hpSend);
                return FALSE;
        }
#endif /* NOT SOCKETS */
        //dprintf1(("Client connected to data pipe -- here we go...\n"));

        /* Create all the queues: Allow up to 10K file names to be queued
           up to 10 files to be packed in advance and 6 buffers of data to be
           read into main storage in advance:
                                  proc  MxMT MnQS MxQ Event   InstData   Name*/
        SendQueue = Queue_Create(SendData, 1, 0,  6, NULL, (DWORD)hpSend, "SendQueue");
        ReadQueue = Queue_Create(ReadInFile, 1, 0, 10, NULL, (DWORD)SendQueue, "ReadQueue");
        PackQueue = Queue_Create(PackFile, 3, 0, 99999, NULL, (DWORD)ReadQueue, "PackQueue");

        /* Abort unless it all worked */
        if (PackQueue==NULL || ReadQueue==NULL || SendQueue==NULL) {
                dprintf1(("Queues for pipe %x failed to Create.  Aborting...\n", hPipe));
                if (PackQueue) Queue_Destroy(PackQueue);
                if (ReadQueue) Queue_Destroy(ReadQueue);
                if (SendQueue) Queue_Destroy(SendQueue);
                CLOSEHANDLE(hpSend);
                return FALSE;           /* Caller will close hPipe */
        }


        /* Collect names from client and enqueue each one */
        for (; ; )
        {       SSNEWREQ Request;       /* message from client */
                DWORD    ActSize;       /* bytes read from (main) pipe */

                if (ReadFile(hPipe, &Request, sizeof(Request), &ActSize, NULL)){
                        if (Request.lVersion>SS_VERSION) {
                                dprintf1(("Bad version %d in file list request on pipe %x\n"
                                , Request.lVersion, hPipe));

                                break;

                        }
                        if (Request.lRequest!=LREQUEST) {
                                dprintf1(("Bad LREQUEST from pipe %x\n", hPipe));

                                break;
                        }
                        if (Request.lCode == -SSREQ_ENDFILES) {
                                dprintf1(("End of client's files list on pipe %x\n", hPipe));

                                /* This is the clean way to end */
                                Queue_Destroy(PackQueue);
                                if (!Started) {
                                        /* OK - so the clever clogs requested zero files */
                                        Queue_Destroy(ReadQueue);
                                        Queue_Destroy(SendQueue);
                                        /* Send a No More Files response */
#ifdef SOCKETS
                                        {
                                            SSNEWRESP resp;

                                            resp.lVersion = SS_VERSION;
                                            resp.lResponse = LRESPONSE;
                                            resp.lCode = SSRESP_END;
                                            resp.ulSize = 0;
                                            resp.ulSum = 0;
                                            resp.ft_lastwrite.dwLowDateTime = 0;
                                            resp.ft_lastwrite.dwHighDateTime = 0;

                                            send(hpSend, (PSTR) &resp, sizeof(resp), 0);
                                        }
#else
                                        ss_sendnewresp( hpSend, SS_VERSION, SSRESP_END
                                                , 0,0, 0,0, NULL);
#endif /* SOCKETS */
                                        CLOSEHANDLE(hpSend);
                                }
                                return TRUE;
                        }
                        if (Request.lCode != -SSREQ_NEXTFILE) {

                                dprintf1(( "Bad code (%d) in files list from pipe %x\n"
                                      , Request.lCode, hPipe));

                                break;
                        }
                }
                else {  DWORD errorcode = GetLastError();
                        switch(errorcode) {

                                case ERROR_NO_DATA:
                                case ERROR_BROKEN_PIPE:
                                        /* pipe connection lost - forget it */
                                        dprintf1(("main pipe %x broken on read\n", hPipe));
                                        break;
                                default:
                                        dprintf1(("read error %d on main pipe %x\n", errorcode, hPipe));
                                        break;
                        }
                        break;
                }
                if (!EnqueueName( PackQueue, Request.szPath
                                , (UINT)((LPBYTE)(&Request) + ActSize - (LPBYTE)(&Request.szPath))
                                )
                   ){
                        break;
                }
                Started = TRUE;
        } /* loop */

        /* only exit this way on error */
        /* Close the queues down.  Allow what's in them to run through */
        Queue_Destroy(PackQueue);
        if (!Started) {
                Queue_Destroy(ReadQueue);
                Queue_Destroy(SendQueue);

        }
        return FALSE;
} /* ss_sendfiles */