OLD | NEW |
| (Empty) |
1 // Copyright 2015 The Crashpad Authors. All rights reserved. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 | |
15 #ifndef CRASHPAD_HANDLER_WIN_REGISTRATION_PIPE_STATE_H_ | |
16 #define CRASHPAD_HANDLER_WIN_REGISTRATION_PIPE_STATE_H_ | |
17 | |
18 #include <windows.h> | |
19 | |
20 #include "base/basictypes.h" | |
21 #include "client/registration_protocol_win.h" | |
22 #include "handler/win/registration_server.h" | |
23 #include "util/win/scoped_handle.h" | |
24 | |
25 namespace crashpad { | |
26 | |
27 //! \brief Implements the state and state transitions of a single named pipe for | |
28 //! the Crashpad client registration protocol for Windows. Each pipe | |
29 //! instance may handle a single client connection at a time. After each | |
30 //! connection completes, whether successfully or otherwise, the instance | |
31 //! will attempt to return to a listening state, ready for a new client | |
32 //! connection. | |
33 class RegistrationPipeState { | |
34 public: | |
35 //! \brief Initializes the state for a single pipe instance. The client must | |
36 //! call Initialize() before clients may connect to this pipe. | |
37 //! \param[in] pipe The named pipe to listen on. | |
38 //! \param[in] delegate The delegate that will be used to handle requests. | |
39 RegistrationPipeState(ScopedFileHANDLE pipe, | |
40 RegistrationServer::Delegate* delegate); | |
41 ~RegistrationPipeState(); | |
42 | |
43 //! \brief Places the pipe in the running state, ready to receive and process | |
44 //! client connections. Before destroying a running RegistrationPipeState | |
45 //! instance you must invoke Stop() and then wait for completion_event() | |
46 //! to be signaled one last time. | |
47 //! \return Returns true if successful, in which case the client must observe | |
48 //! completion_event() and invoke OnCompletion() whenever it is signaled. | |
49 bool Initialize(); | |
50 | |
51 //! \brief Cancels any pending asynchronous operations. After invoking this | |
52 //! method you must wait for completion_event() to be signaled before | |
53 //! destroying the instance. | |
54 void Stop(); | |
55 | |
56 //! \brief Returns an event handle that will be signaled whenever an | |
57 //! asynchronous operation associated with this instance completes. | |
58 HANDLE completion_event() { return event_.get(); } | |
59 | |
60 //! \brief Must be called by the client whenever completion_event() is | |
61 //! signaled. | |
62 //! \return Returns true if the pipe is still in the running state. Otherwise, | |
63 //! a permanent failure has occurred and the instance may be immediately | |
64 //! destroyed. | |
65 bool OnCompletion(); | |
66 | |
67 private: | |
68 using AsyncCompletionHandler = | |
69 bool (RegistrationPipeState::*)(DWORD bytes_transferred); | |
70 | |
71 // State transition handlers. Return true if the pipe is still valid. | |
72 | |
73 bool OnConnectComplete(DWORD /* bytes_transferred */); | |
74 bool OnReadComplete(DWORD bytes_transferred); | |
75 bool OnWriteComplete(DWORD bytes_transferred); | |
76 bool OnWaitForClientCloseComplete(DWORD bytes_transferred); | |
77 | |
78 // Pipe operations. Return true if the pipe is still valid. | |
79 | |
80 // Prepares the pipe to accept a new client connecion. | |
81 bool IssueConnect(); | |
82 // Reads into |request_|. | |
83 bool IssueRead(); | |
84 // Writes from |response_|. | |
85 bool IssueWrite(); | |
86 // Issues a final ReadFile() that is expected to be terminated when the client | |
87 // closes the pipe. | |
88 bool IssueWaitForClientClose(); | |
89 // Processes |request_| using |delegate_| and stores the result in | |
90 // |response_|. | |
91 bool HandleRequest(); | |
92 // Closes the active connection and invokes IssueConnect(). | |
93 bool ResetConnection(); | |
94 | |
95 RegistrationRequest request_; | |
96 RegistrationResponse response_; | |
97 // The state transition handler to be invoked when the active asynchronous | |
98 // operation completes. | |
99 AsyncCompletionHandler completion_handler_; | |
100 OVERLAPPED overlapped_; | |
101 ScopedKernelHANDLE event_; | |
102 ScopedFileHANDLE pipe_; | |
103 bool waiting_for_close_; | |
104 RegistrationServer::Delegate* delegate_; | |
105 decltype(GetNamedPipeClientProcessId)* get_named_pipe_client_process_id_proc_; | |
106 | |
107 DISALLOW_COPY_AND_ASSIGN(RegistrationPipeState); | |
108 }; | |
109 | |
110 } // namespace crashpad | |
111 | |
112 #endif // CRASHPAD_HANDLER_WIN_REGISTRATION_PIPE_STATE_H_ | |
OLD | NEW |