/samples/snippets/cpp/VS_Snippets_CLR_System/system.IO.Pipes.NamedPipeServerStream_ImpersonationSample1/cpp/program.cpp

https://github.com/dotnet/dotnet-api-docs · C++ · 160 lines · 121 code · 24 blank · 15 comment · 7 complexity · 6d88bc1dc1a516bbf59f496c5876395b MD5 · raw file

  1. //<snippet01>
  2. #using <System.Core.dll>
  3. using namespace System;
  4. using namespace System::IO;
  5. using namespace System::IO::Pipes;
  6. using namespace System::Text;
  7. using namespace System::Threading;
  8. // Defines the data protocol for reading and writing strings on our stream
  9. public ref class StreamString
  10. {
  11. private:
  12. Stream^ ioStream;
  13. UnicodeEncoding^ streamEncoding;
  14. public:
  15. StreamString(Stream^ ioStream)
  16. {
  17. this->ioStream = ioStream;
  18. streamEncoding = gcnew UnicodeEncoding();
  19. }
  20. String^ ReadString()
  21. {
  22. int len;
  23. len = ioStream->ReadByte() * 256;
  24. len += ioStream->ReadByte();
  25. array<Byte>^ inBuffer = gcnew array<Byte>(len);
  26. ioStream->Read(inBuffer, 0, len);
  27. return streamEncoding->GetString(inBuffer);
  28. }
  29. int WriteString(String^ outString)
  30. {
  31. array<Byte>^ outBuffer = streamEncoding->GetBytes(outString);
  32. int len = outBuffer->Length;
  33. if (len > UInt16::MaxValue)
  34. {
  35. len = (int)UInt16::MaxValue;
  36. }
  37. ioStream->WriteByte((Byte)(len / 256));
  38. ioStream->WriteByte((Byte)(len & 255));
  39. ioStream->Write(outBuffer, 0, len);
  40. ioStream->Flush();
  41. return outBuffer->Length + 2;
  42. }
  43. };
  44. // Contains the method executed in the context of the impersonated user
  45. public ref class ReadFileToStream
  46. {
  47. private:
  48. String^ fn;
  49. StreamString ^ss;
  50. public:
  51. ReadFileToStream(StreamString^ str, String^ filename)
  52. {
  53. fn = filename;
  54. ss = str;
  55. }
  56. void Start()
  57. {
  58. String^ contents = File::ReadAllText(fn);
  59. ss->WriteString(contents);
  60. }
  61. };
  62. public ref class PipeServer
  63. {
  64. private:
  65. static int numThreads = 4;
  66. public:
  67. static void Main()
  68. {
  69. int i;
  70. array<Thread^>^ servers = gcnew array<Thread^>(numThreads);
  71. Console::WriteLine("\n*** Named pipe server stream with impersonation example ***\n");
  72. Console::WriteLine("Waiting for client connect...\n");
  73. for (i = 0; i < numThreads; i++)
  74. {
  75. servers[i] = gcnew Thread(gcnew ThreadStart(&ServerThread));
  76. servers[i]->Start();
  77. }
  78. Thread::Sleep(250);
  79. while (i > 0)
  80. {
  81. for (int j = 0; j < numThreads; j++)
  82. {
  83. if (servers[j] != nullptr)
  84. {
  85. if (servers[j]->Join(250))
  86. {
  87. Console::WriteLine("Server thread[{0}] finished.", servers[j]->ManagedThreadId);
  88. servers[j] = nullptr;
  89. i--; // decrement the thread watch count
  90. }
  91. }
  92. }
  93. }
  94. Console::WriteLine("\nServer threads exhausted, exiting.");
  95. }
  96. private:
  97. static void ServerThread()
  98. {
  99. NamedPipeServerStream^ pipeServer =
  100. gcnew NamedPipeServerStream("testpipe", PipeDirection::InOut, numThreads);
  101. int threadId = Thread::CurrentThread->ManagedThreadId;
  102. // Wait for a client to connect
  103. pipeServer->WaitForConnection();
  104. Console::WriteLine("Client connected on thread[{0}].", threadId);
  105. try
  106. {
  107. //<snippet2>
  108. // Read the request from the client. Once the client has
  109. // written to the pipe its security token will be available.
  110. StreamString^ ss = gcnew StreamString(pipeServer);
  111. // Verify our identity to the connected client using a
  112. // string that the client anticipates.
  113. ss->WriteString("I am the one true server!");
  114. String^ filename = ss->ReadString();
  115. // Read in the contents of the file while impersonating the client.
  116. ReadFileToStream^ fileReader = gcnew ReadFileToStream(ss, filename);
  117. // Display the name of the user we are impersonating.
  118. Console::WriteLine("Reading file: {0} on thread[{1}] as user: {2}.",
  119. filename, threadId, pipeServer->GetImpersonationUserName());
  120. pipeServer->RunAsClient(gcnew PipeStreamImpersonationWorker(fileReader, &ReadFileToStream::Start));
  121. //</snippet2>
  122. }
  123. // Catch the IOException that is raised if the pipe is broken
  124. // or disconnected.
  125. catch (IOException^ e)
  126. {
  127. Console::WriteLine("ERROR: {0}", e->Message);
  128. }
  129. pipeServer->Close();
  130. }
  131. };
  132. int main()
  133. {
  134. PipeServer::Main();
  135. }
  136. //</snippet01>