示例#1
0
DWORD PipeReader::startServer() {
	SECURITY_ATTRIBUTES sa;
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = FALSE;
	CreateMyDACL(&sa);

	wchar_t temp[300];
	swprintf(temp,L"\\\\.\\pipe\\%s",pipeName);
	HANDLE _pipe=CreateNamedPipe(temp,PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,PIPE_TYPE_BYTE,PIPE_UNLIMITED_INSTANCES,0,0,0,&sa);
	swprintf(temp,L"\\\\.\\pipe\\%s",pipeEventName);
	HANDLE _eventpipe=CreateNamedPipe(temp,PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,PIPE_TYPE_BYTE,PIPE_UNLIMITED_INSTANCES,0,0,0,&sa);
	wchar_t log[300];
	swprintf(log,L"[BixVReader]Pipe created:%s:%p",pipeName,_pipe);
	OutputDebugString(log);

	while (true) {
		//__try {
			BOOL ris=ConnectNamedPipe(_pipe,NULL);
			if (ris==0) {
				swprintf(log,L"[BixVReader]Pipe NOT connected:%x",GetLastError());
				OutputDebugString(log);
			}
			else {
				swprintf(log,L"[BixVReader]Pipe connected");
				OutputDebugString(log);
				}
			ris=ConnectNamedPipe(_eventpipe,NULL);
			if (ris==0) {
				swprintf(log,L"[BixVReader]Event Pipe NOT connected:%x",GetLastError());
				OutputDebugString(log);
			}
			else {
				swprintf(log,L"[BixVReader]Event Pipe connected");
				OutputDebugString(log);
			}
			pipe=_pipe;
			eventpipe=_eventpipe;
			if (!waitInsertIpr.empty()) {
				// if I'm waiting for card insertion, verify if there's a card present
				if (initProtocols()) {
					SectionLocker lock(device->m_RequestLock);
					while (!waitInsertIpr.empty()) {
						CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
						if (ipr->UnmarkCancelable()==S_OK) {
							ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
						}
						waitInsertIpr.pop_back();
					}
					state=SCARD_SWALLOWED;
				}
			}

			while (true) {
				// wait for a command
				DWORD command=0;
				DWORD read=0;
				if (!ReadFile(eventpipe,&command,sizeof(DWORD),&read,NULL)) {
					state=SCARD_ABSENT;
					OutputDebugString(L"[BixVReader]Pipe error");
					powered=0;
					pipe=NULL;
					eventpipe=NULL;
					if (!waitRemoveIpr.empty()) {
						// card inserted
						SectionLocker lock(device->m_RequestLock);
						while (!waitRemoveIpr.empty()) {
							CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
							OutputDebugString(L"[BixVReader]complete Wait Remove");
							if (ipr->UnmarkCancelable()==S_OK) {
								OutputDebugString(L"[BixVReader]Wait Remove Unmarked");
								ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
								OutputDebugString(L"[BixVReader]Wait Remove Completed");
							}
							waitRemoveIpr.pop_back();
						}
					}
					if (!waitInsertIpr.empty()) {
						// card removed
						SectionLocker lock(device->m_RequestLock);
						while (!waitInsertIpr.empty()) {
							CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
							OutputDebugString(L"[BixVReader]cancel Wait Remove");
							if (ipr->UnmarkCancelable()==S_OK) {
								OutputDebugString(L"[BixVReader]Wait Insert Unmarked");
								ipr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
								OutputDebugString(L"[BixVReader]Wait Insert Cancelled");
							}
							waitInsertIpr.pop_back();
						}
					}
					DisconnectNamedPipe(_pipe);
					DisconnectNamedPipe(_eventpipe);
					break;
				}
				OutputDebugString(L"[BixVReader]Pipe data");
				if (command==0)
					powered=0;
				if (command==0 && !waitRemoveIpr.empty()) {
					// card removed
					SectionLocker lock(device->m_RequestLock);
					state=SCARD_ABSENT;
					while (!waitRemoveIpr.empty()) {
						CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
						if (ipr->UnmarkCancelable()==S_OK)
							ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
						waitRemoveIpr.pop_back();
					}
				}
				else if (command==1 && !waitInsertIpr.empty()) {
					// card inserted
					SectionLocker lock(device->m_RequestLock);
					state=SCARD_SWALLOWED;
					initProtocols();
					while (!waitInsertIpr.empty()) {
						CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
						if (ipr->UnmarkCancelable()==S_OK)
							ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
						waitInsertIpr.pop_back();
					}
				}
			}
		//}
		//__except(EXCEPTION_EXECUTE_HANDLER) {
		//	wchar_t log[300];
		//	DWORD err=GetExceptionCode();
		//	swprintf(log,L"Exception:%08X",err);
		//	OutputDebugString(log);
		//}
	}
	OutputDebugString(L"[BixVReader]Pipe quit!!!");
	return 0;
}
示例#2
0
//
//  FUNCTION: ServiceStart
//
//  PURPOSE: Actual code of the service that does the work.
//
//  PARAMETERS:
//    dwArgc   - number of command line arguments
//    lpszArgv - array of command line arguments
//
//  RETURN VALUE:
//    none
//
//  COMMENTS:
//    The default behavior is to open a
//    named pipe, \\.\pipe\simple, and read
//    from it.  It the modifies the data and
//    writes it back to the pipe.  The service
//    stops when hServerStopEvent is signalled
//
VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
{
   HANDLE                  hPipe = INVALID_HANDLE_VALUE;
   HANDLE                  hEvents[2] = {NULL, NULL};
   OVERLAPPED              os;
   PSECURITY_DESCRIPTOR    pSD = NULL;
   SECURITY_ATTRIBUTES     sa;
   TCHAR                   szIn[80];
   TCHAR                   szOut[ (sizeof(szIn) / sizeof(TCHAR) )  + 100];
   LPTSTR                  lpszPipeName = TEXT("\\\\.\\pipe\\simple");
   BOOL                    bRet;
   DWORD                   cbRead;
   DWORD                   cbWritten;
   DWORD                   dwWait;
   UINT                    ndx;

   ///////////////////////////////////////////////////
   //
   // Service initialization
   //

   // report the status to the service control manager.
   //
   if (!ReportStatusToSCMgr(
                           SERVICE_START_PENDING, // service state
                           NO_ERROR,              // exit code
                           3000))                 // wait hint
      goto cleanup;

   // create the event object. The control handler function signals
   // this event when it receives the "stop" control code.
   //
   hServerStopEvent = CreateEvent(
                                 NULL,    // no security attributes
                                 TRUE,    // manual reset event
                                 FALSE,   // not-signalled
                                 NULL);   // no name

   if ( hServerStopEvent == NULL)
      goto cleanup;

   hEvents[0] = hServerStopEvent;

   // report the status to the service control manager.
   //
   if (!ReportStatusToSCMgr(
                           SERVICE_START_PENDING, // service state
                           NO_ERROR,              // exit code
                           3000))                 // wait hint
      goto cleanup;

   // create the event object object use in overlapped i/o
   //
   hEvents[1] = CreateEvent(
                           NULL,    // no security attributes
                           TRUE,    // manual reset event
                           FALSE,   // not-signalled
                           NULL);   // no name

   if ( hEvents[1] == NULL)
      goto cleanup;

   // report the status to the service control manager.
   //
   if (!ReportStatusToSCMgr(
                           SERVICE_START_PENDING, // service state
                           NO_ERROR,              // exit code
                           3000))                 // wait hint
      goto cleanup;

   // create a security descriptor that allows anyone to write to
   //  the pipe...
   //
   pSD = (PSECURITY_DESCRIPTOR) malloc( SECURITY_DESCRIPTOR_MIN_LENGTH );

   if (pSD == NULL)
      goto cleanup;

   if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
      goto cleanup;

   sa.nLength = sizeof(sa);
   sa.bInheritHandle = TRUE;
   sa.lpSecurityDescriptor = pSD;

   if(!CreateMyDACL(&sa) )
   {
       // DACL creation FAILED!!
       return;
   }

   // report the status to the service control manager.
   //
   if (!ReportStatusToSCMgr(
                           SERVICE_START_PENDING, // service state
                           NO_ERROR,              // exit code
                           3000))                 // wait hint
      goto cleanup;


   // allow user tp define pipe name
   for ( ndx = 1; ndx < dwArgc-1; ndx++ )
   {

      if ( ( (*(lpszArgv[ndx]) == TEXT('-')) ||
             (*(lpszArgv[ndx]) == TEXT('/')) ) &&
           (!_tcsicmp( TEXT("pipe"), lpszArgv[ndx]+1 ) && ((ndx + 1) < dwArgc)) )
      {
         lpszPipeName = lpszArgv[++ndx];
      }

   }

   // open our named pipe...
   //
   hPipe = CreateNamedPipe(
                          lpszPipeName         ,  // name of pipe
                          FILE_FLAG_OVERLAPPED |
                          PIPE_ACCESS_DUPLEX,     // pipe open mode
                          PIPE_TYPE_MESSAGE |
                          PIPE_READMODE_MESSAGE |
                          PIPE_WAIT,              // pipe IO type
                          1,                      // number of instances
                          0,                      // size of outbuf (0 == allocate as necessary)
                          0,                      // size of inbuf
                          1000,                   // default time-out value
                          &sa);                   // security attributes

   if (hPipe == INVALID_HANDLE_VALUE)
   {
      AddToMessageLog(TEXT("Unable to create named pipe"));
      goto cleanup;
   }


   // report the status to the service control manager.
   //
   if (!ReportStatusToSCMgr(
                           SERVICE_RUNNING,       // service state
                           NO_ERROR,              // exit code
                           0))                    // wait hint
      goto cleanup;

   //
   // End of initialization
   //
   ////////////////////////////////////////////////////////

   ////////////////////////////////////////////////////////
   //
   // Service is now running, perform work until shutdown
   //

   for(;;)
   {
      // init the overlapped structure
      //
      memset( &os, 0, sizeof(OVERLAPPED) );
      os.hEvent = hEvents[1];
      ResetEvent( hEvents[1] );


      // wait for a connection...
      //
      ConnectNamedPipe(hPipe, &os);

      if ( GetLastError() == ERROR_IO_PENDING )
      {
         dwWait = WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE );
         if ( dwWait != WAIT_OBJECT_0+1 )     // not overlapped i/o event - error occurred,
            break;                           // or server stop signaled
      }

      // init the overlapped structure
      //
      memset( &os, 0, sizeof(OVERLAPPED) );
      os.hEvent = hEvents[1];
      ResetEvent( hEvents[1] );


     // Set the buffer to all NULLs otherwise we get leftover characters
      memset(szIn, '\0', sizeof(szIn));

      // grab whatever's coming through the pipe...
      //
      bRet = ReadFile(
                     hPipe,          // file to read from
                     szIn,           // address of input buffer
                     sizeof(szIn),   // number of bytes to read
                     &cbRead,        // number of bytes read
                     &os);           // overlapped stuff, not needed

      if ( !bRet && ( GetLastError() == ERROR_IO_PENDING ) )
      {
         dwWait = WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE );
         if ( dwWait != WAIT_OBJECT_0+1 )     // not overlapped i/o event - error occurred,
            break;                           // or server stop signaled
      }

      // munge the string
      //
      StringCchPrintf(szOut, sizeof(szOut),TEXT("Hello! [%s]"), szIn);

      // init the overlapped structure
      //
      memset( &os, 0, sizeof(OVERLAPPED) );
      os.hEvent = hEvents[1];
      ResetEvent( hEvents[1] );

      // send it back out...
      //
      bRet = WriteFile(
                      hPipe,          // file to write to
                      szOut,          // address of output buffer
                      sizeof(szOut),  // number of bytes to write
                      &cbWritten,     // number of bytes written
                      &os);           // overlapped stuff, not needed


      if ( !bRet && ( GetLastError() == ERROR_IO_PENDING ) )
      {
         dwWait = WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE );
         if ( dwWait != WAIT_OBJECT_0+1 )     // not overlapped i/o event - error occurred,
            break;                           // or server stop signaled
      }

      // drop the connection...
      //
      DisconnectNamedPipe(hPipe);
   }

   cleanup:

   if (hPipe != INVALID_HANDLE_VALUE )
      CloseHandle(hPipe);

   if (hServerStopEvent)
      CloseHandle(hServerStopEvent);

   if (hEvents[1]) // overlapped i/o event
      CloseHandle(hEvents[1]);

   if ( pSD )
      free( pSD );

}