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; }
// // 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 ); }