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_UTIL_WIN_REGISTRATION_PROTOCOL_WIN_H_ 16 #define CRASHPAD_UTIL_WIN_REGISTRATION_PROTOCOL_WIN_H_ 17 18 #include <windows.h> 19 #include <stdint.h> 20 21 #include <string> 22 23 #include "util/win/address_types.h" 24 25 namespace crashpad { 26 27 #pragma pack(push, 1) 28 29 //! \brief Structure read out of the client process by the crash handler when an 30 //! exception occurs. 31 struct ExceptionInformation { 32 //! \brief The address of an EXCEPTION_POINTERS structure in the client 33 //! process that describes the exception. 34 WinVMAddress exception_pointers; 35 36 //! \brief The thread on which the exception happened. 37 DWORD thread_id; 38 }; 39 40 //! \brief A client registration request. 41 struct RegistrationRequest { 42 //! \brief The expected value of `version`. This should be changed whenever 43 //! the messages or ExceptionInformation are modified incompatibly. 44 enum { kMessageVersion = 1 }; 45 46 //! \brief Version field to detect skew between client and server. Should be 47 //! set to kMessageVersion. 48 int version; 49 50 //! \brief The PID of the client process. 51 DWORD client_process_id; 52 53 //! \brief The address, in the client process's address space, of an 54 //! ExceptionInformation structure, used when handling a crash dump 55 //! request. 56 WinVMAddress crash_exception_information; 57 58 //! \brief The address, in the client process's address space, of an 59 //! ExceptionInformation structure, used when handling a non-crashing dump 60 //! request. 61 WinVMAddress non_crash_exception_information; 62 63 //! \brief The address, in the client process's address space, of a 64 //! `CRITICAL_SECTION` allocated with a valid .DebugInfo field. This can 65 //! be accomplished by using 66 //! InitializeCriticalSectionWithDebugInfoIfPossible() or equivalent. This 67 //! value can be `0`, however then limited lock data will be available in 68 //! minidumps. 69 WinVMAddress critical_section_address; 70 }; 71 72 //! \brief A message only sent to the server by itself to trigger shutdown. 73 struct ShutdownRequest { 74 //! \brief A randomly generated token used to validate the the shutdown 75 //! request was not sent from another process. 76 uint64_t token; 77 }; 78 79 //! \brief The message passed from client to server by 80 //! SendToCrashHandlerServer(). 81 struct ClientToServerMessage { 82 //! \brief Indicates which field of the union is in use. 83 enum Type : uint32_t { 84 //! \brief For RegistrationRequest. 85 kRegister, 86 87 //! \brief For ShutdownRequest. 88 kShutdown, 89 90 //! \brief An empty message sent by the initial client in asynchronous mode. 91 //! No data is required, this just confirms that the server is ready to 92 //! accept client registrations. 93 kPing, 94 } type; 95 96 union { 97 RegistrationRequest registration; 98 ShutdownRequest shutdown; 99 }; 100 }; 101 102 //! \brief A client registration response. 103 struct RegistrationResponse { 104 //! \brief An event `HANDLE`, valid in the client process, that should be 105 //! signaled to request a crash report. Clients should convert the value 106 //! to a `HANDLE` by calling IntToHandle(). 107 int request_crash_dump_event; 108 109 //! \brief An event `HANDLE`, valid in the client process, that should be 110 //! signaled to request a non-crashing dump be taken. Clients should 111 //! convert the value to a `HANDLE` by calling IntToHandle(). 112 int request_non_crash_dump_event; 113 114 //! \brief An event `HANDLE`, valid in the client process, that will be 115 //! signaled by the server when the non-crashing dump is complete. Clients 116 //! should convert the value to a `HANDLE` by calling IntToHandle(). 117 int non_crash_dump_completed_event; 118 }; 119 120 //! \brief The response sent back to the client via SendToCrashHandlerServer(). 121 union ServerToClientMessage { 122 RegistrationResponse registration; 123 }; 124 125 #pragma pack(pop) 126 127 //! \brief Connect over the given \a pipe_name, passing \a message to the 128 //! server, storing the server's reply into \a response. 129 //! 130 //! Typically clients will not use this directly, instead using 131 //! CrashpadClient::SetHandler(). 132 //! 133 //! \sa CrashpadClient::SetHandler() 134 bool SendToCrashHandlerServer(const std::wstring& pipe_name, 135 const ClientToServerMessage& message, 136 ServerToClientMessage* response); 137 138 //! \brief Wraps CreateNamedPipe() to create a single named pipe instance. 139 //! 140 //! \param[in] pipe_name The name to use for the pipe. 141 //! \param[in] first_instance If `true`, the named pipe instance will be 142 //! created with `FILE_FLAG_FIRST_PIPE_INSTANCE`. This ensures that the the 143 //! pipe name is not already in use when created. The first instance will be 144 //! created with an untrusted integrity SACL so instances of this pipe can 145 //! be connected to by processes of any integrity level. 146 HANDLE CreateNamedPipeInstance(const std::wstring& pipe_name, 147 bool first_instance); 148 149 //! \brief Returns the `SECURITY_DESCRIPTOR` blob that will be used for creating 150 //! the connection pipe in CreateNamedPipeInstance(). 151 //! 152 //! This function is only exposed for testing. 153 //! 154 //! \param[out] size The size of the returned blob. May be `nullptr` if not 155 //! required. 156 //! 157 //! \return A pointer to a self-relative `SECURITY_DESCRIPTOR`. Ownership is not 158 //! transferred to the caller. 159 const void* GetSecurityDescriptorForNamedPipeInstance(size_t* size); 160 161 //! \brief Returns the `SECURITY_DESCRIPTOR` blob that will be used for creating 162 //! the connection pipe in CreateNamedPipeInstance() if the full descriptor 163 //! can't be created. 164 //! 165 //! This function is only exposed for testing. 166 //! 167 //! \param[out] size The size of the returned blob. May be `nullptr` if not 168 //! required. 169 //! 170 //! \return A pointer to a self-relative `SECURITY_DESCRIPTOR`. Ownership is not 171 //! transferred to the caller. 172 const void* GetFallbackSecurityDescriptorForNamedPipeInstance(size_t* size); 173 174 } // namespace crashpad 175 176 #endif // CRASHPAD_UTIL_WIN_REGISTRATION_PROTOCOL_WIN_H_ 177