crash_generation_app.cc revision 9033edcd7bab5a25c748dd1979f51853bbe06f87
1eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// Copyright (c) 2008, Google Inc.
2eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// All rights reserved.
3eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//
4eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// Redistribution and use in source and binary forms, with or without
5eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// modification, are permitted provided that the following conditions are
6eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// met:
7eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//
8eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//     * Redistributions of source code must retain the above copyright
9eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// notice, this list of conditions and the following disclaimer.
10eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//     * Redistributions in binary form must reproduce the above
11eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// copyright notice, this list of conditions and the following disclaimer
12eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// in the documentation and/or other materials provided with the
13eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// distribution.
14eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//     * Neither the name of Google Inc. nor the names of its
15eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// contributors may be used to endorse or promote products derived from
16eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// this software without specific prior written permission.
17eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//
18eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
30eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// crash_generation_app.cpp : Defines the entry point for the application.
31eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//
32eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
33eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai#include "precompile.h"
34eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
35eeca9921c563d802cccc5593bf55dcb7683e7250mmentovainamespace google_breakpad {
36eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
37eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiconst int kMaxLoadString = 100;
3835c34d6bb9b1deb656bfe65741f2c4f8401045f4doshimunconst wchar_t kPipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\S-1-5-21-39260824-743453154-142223018-195347";
39eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
40eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiconst DWORD kEditBoxStyles = WS_CHILD |
41eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                             WS_VISIBLE |
42eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                             WS_VSCROLL |
43eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                             ES_LEFT |
44eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                             ES_MULTILINE |
45eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                             ES_AUTOVSCROLL |
46eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                             ES_READONLY;
47eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
48eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// Maximum length of a line in the edit box.
49eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiconst size_t kMaximumLineLength = 256;
50eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
51eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// CS to access edit control in a thread safe way.
52eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaistatic CRITICAL_SECTION* cs_edit = NULL;
53eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
54eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// Edit control.
55eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaistatic HWND client_status_edit_box;
56eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
57eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiHINSTANCE current_instance;             // Current instance.
58eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiTCHAR title[kMaxLoadString];            // Title bar text.
59eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiTCHAR window_class[kMaxLoadString];     // Main window class name.
60eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
61eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiATOM MyRegisterClass(HINSTANCE instance);
62eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiBOOL InitInstance(HINSTANCE, int);
63eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiLRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
64eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiINT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
65eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
66eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaistatic ExceptionHandler* handler = NULL;
67eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaistatic CrashGenerationServer* crash_server = NULL;
68eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
69eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// Registers the window class.
70eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//
71eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// This function and its usage are only necessary if you want this code
72eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// to be compatible with Win32 systems prior to the 'RegisterClassEx'
73eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// function that was added to Windows 95. It is important to call this
74eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// function so that the application will get 'well formed' small icons
75eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// associated with it.
76eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiATOM MyRegisterClass(HINSTANCE instance) {
77eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  WNDCLASSEX wcex;
78eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  wcex.cbSize = sizeof(WNDCLASSEX);
79eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  wcex.style = CS_HREDRAW | CS_VREDRAW;
80eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  wcex.lpfnWndProc = WndProc;
81eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  wcex.cbClsExtra = 0;
82eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  wcex.cbWndExtra = 0;
83eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  wcex.hInstance = instance;
84eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  wcex.hIcon = LoadIcon(instance,
85eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                        MAKEINTRESOURCE(IDI_CRASHGENERATIONAPP));
86eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
87eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
88eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  wcex.lpszMenuName = MAKEINTRESOURCE(IDC_CRASHGENERATIONAPP);
89eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  wcex.lpszClassName = window_class;
90eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
91eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
92eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  return RegisterClassEx(&wcex);
93eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
94eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
95eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// Saves instance handle and creates main window
96eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//
97eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// In this function, we save the instance handle in a global variable and
98eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//   create and display the main program window.
99eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiBOOL InitInstance(HINSTANCE instance, int command_show) {
100eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  current_instance = instance;
101eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  HWND wnd = CreateWindow(window_class,
102eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          title,
103eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          WS_OVERLAPPEDWINDOW,
104eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          CW_USEDEFAULT,
105eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          0,
106eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          CW_USEDEFAULT,
107eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          0,
108eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          NULL,
109eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          NULL,
110eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          instance,
111eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          NULL);
112eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
113eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  if (!wnd) {
114eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    return FALSE;
115eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
116eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
117eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  ShowWindow(wnd, command_show);
118eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  UpdateWindow(wnd);
119eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
120eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  return TRUE;
121eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
122eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
123eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaistatic void AppendTextToEditBox(TCHAR* text) {
124eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  EnterCriticalSection(cs_edit);
125eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  SYSTEMTIME current_time;
126eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  GetLocalTime(&current_time);
127eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  TCHAR line[kMaximumLineLength];
128eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  int result = swprintf_s(line,
129eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          kMaximumLineLength,
130eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          L"[%.2d-%.2d-%.4d %.2d:%.2d:%.2d] %s",
131eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          current_time.wMonth,
132eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          current_time.wDay,
133eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          current_time.wYear,
134eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          current_time.wHour,
135eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          current_time.wMinute,
136eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          current_time.wSecond,
137eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          text);
138eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
139eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  if (result == -1) {
140eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    return;
141eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
142eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
143eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  int length = GetWindowTextLength(client_status_edit_box);
144eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  SendMessage(client_status_edit_box,
145eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai              EM_SETSEL,
146eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai              (WPARAM)length,
147eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai              (LPARAM)length);
148eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  SendMessage(client_status_edit_box,
149eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai              EM_REPLACESEL,
150eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai              (WPARAM)FALSE,
151eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai              (LPARAM)line);
152eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  LeaveCriticalSection(cs_edit);
153eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
154eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
155eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaistatic DWORD WINAPI AppendTextWorker(void* context) {
156eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  TCHAR* text = reinterpret_cast<TCHAR*>(context);
157eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
158eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  AppendTextToEditBox(text);
159eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  delete[] text;
160eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
161eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  return 0;
162eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
163eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
164c79141e306dc44eff2d3646ddc153b7dfc128d21doshimun@gmail.combool ShowDumpResults(const wchar_t* dump_path,
165c79141e306dc44eff2d3646ddc153b7dfc128d21doshimun@gmail.com                     const wchar_t* minidump_id,
166c79141e306dc44eff2d3646ddc153b7dfc128d21doshimun@gmail.com                     void* context,
167c79141e306dc44eff2d3646ddc153b7dfc128d21doshimun@gmail.com                     EXCEPTION_POINTERS* exinfo,
168c79141e306dc44eff2d3646ddc153b7dfc128d21doshimun@gmail.com                     MDRawAssertionInfo* assertion,
169eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                     bool succeeded) {
170eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  TCHAR* text = new TCHAR[kMaximumLineLength];
171eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  int result = swprintf_s(text,
172eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          kMaximumLineLength,
173eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          TEXT("Dump generation request %s\r\n"),
174eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          succeeded ? TEXT("succeeded") : TEXT("failed"));
175eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  if (result == -1) {
176eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    delete [] text;
177eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
178eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
179eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  AppendTextWorker(text);
180eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  return succeeded;
181eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
182eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
183eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaistatic void _cdecl ShowClientConnected(void* context,
184eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                       const ClientInfo* client_info) {
185eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  TCHAR* line = new TCHAR[kMaximumLineLength];
186eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  int result = swprintf_s(line,
187eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          kMaximumLineLength,
188eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          L"Client connected:\t\t%d\r\n",
189eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          client_info->pid());
190eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
191eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  if (result == -1) {
192eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    delete[] line;
193eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    return;
194eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
195eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
196eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  QueueUserWorkItem(AppendTextWorker, line, WT_EXECUTEDEFAULT);
197eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
198eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
199eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaistatic void _cdecl ShowClientCrashed(void* context,
2009033edcd7bab5a25c748dd1979f51853bbe06f87doshimun                                     const ClientInfo* client_info,
2019033edcd7bab5a25c748dd1979f51853bbe06f87doshimun                                     const wstring* dump_path) {
202eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  TCHAR* line = new TCHAR[kMaximumLineLength];
203eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  int result = swprintf_s(line,
204eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          kMaximumLineLength,
205eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          TEXT("Client requested dump:\t%d\r\n"),
206eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          client_info->pid());
207eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
208eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  if (result == -1) {
209eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    delete[] line;
210eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    return;
211eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
212eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
213eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  QueueUserWorkItem(AppendTextWorker, line, WT_EXECUTEDEFAULT);
214eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
215eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
216eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaistatic void _cdecl ShowClientExited(void* context,
217eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                    const ClientInfo* client_info) {
218eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  TCHAR* line = new TCHAR[kMaximumLineLength];
219eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  int result = swprintf_s(line,
220eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          kMaximumLineLength,
221eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          TEXT("Client exited:\t\t%d\r\n"),
222eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                          client_info->pid());
223eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
224eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  if (result == -1) {
225eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    delete[] line;
226eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    return;
227eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
228eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
229eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  QueueUserWorkItem(AppendTextWorker, line, WT_EXECUTEDEFAULT);
230eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
231eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
232eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaivoid CrashServerStart() {
233eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Do not create another instance of the server.
234eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  if (crash_server) {
235eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    return;
236eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
237eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
238eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  std::wstring dump_path = L"C:\\Dumps\\";
239eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  crash_server = new CrashGenerationServer(kPipeName,
24035c34d6bb9b1deb656bfe65741f2c4f8401045f4doshimun                                           NULL,
241eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                           ShowClientConnected,
242eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                           NULL,
243eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                           ShowClientCrashed,
244eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                           NULL,
245eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                           ShowClientExited,
246eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                           NULL,
247eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                           true,
248eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                           &dump_path);
249eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
250eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  if (!crash_server->Start()) {
251eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    MessageBoxW(NULL, L"Unable to start server", L"Dumper", MB_OK);
252eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    delete crash_server;
253eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    crash_server = NULL;
254eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
255eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
256eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
257eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaivoid CrashServerStop() {
258eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  delete crash_server;
259eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  crash_server = NULL;
260eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
261eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
262eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaivoid DerefZeroCrash() {
263eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  int* x = 0;
264eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  *x = 1;
265eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
266eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
267eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaivoid InvalidParamCrash() {
268eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  printf(NULL);
269eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
270eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
271eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaivoid PureCallCrash() {
272eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  Derived derived;
273eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
274eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
275eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaivoid RequestDump() {
276eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  if (!handler->WriteMinidump()) {
277eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    MessageBoxW(NULL, L"Dump request failed", L"Dumper", MB_OK);
278eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
279eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
280eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
281eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaivoid CleanUp() {
282eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  if (cs_edit) {
283eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    DeleteCriticalSection(cs_edit);
284eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    delete cs_edit;
285eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
286eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
287eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  if (handler) {
288eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    delete handler;
289eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
290eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
291eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  if (crash_server) {
292eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    delete crash_server;
293eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
294eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
295eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
296eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// Processes messages for the main window.
297eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai//
298eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// WM_COMMAND	- process the application menu.
299eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// WM_PAINT	- Paint the main window.
300eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// WM_DESTROY	- post a quit message and return.
301eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiLRESULT CALLBACK WndProc(HWND wnd,
302eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                         UINT message,
303eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                         WPARAM w_param,
304eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                         LPARAM l_param) {
305eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  int message_id;
306eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  int message_event;
307eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  PAINTSTRUCT ps;
308eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  HDC hdc;
309eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
310eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai#pragma warning(push)
311eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai#pragma warning(disable:4312)
312eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Disable warning	C4312: 'type cast' : conversion from 'LONG' to
313eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // 'HINSTANCE' of greater size.
314eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // The value returned by GetwindowLong in the case below returns unsigned.
315eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  HINSTANCE instance = (HINSTANCE)GetWindowLong(wnd, GWL_HINSTANCE);
316eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai#pragma warning(pop)
317eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
318eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  switch (message) {
319eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    case WM_COMMAND:
320eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      // Parse the menu selections.
321eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      message_id = LOWORD(w_param);
322eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      message_event = HIWORD(w_param);
323eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      switch (message_id) {
324eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai        case IDM_ABOUT:
325eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          DialogBox(current_instance,
326eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                    MAKEINTRESOURCE(IDD_ABOUTBOX),
327eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                    wnd,
328eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                    About);
329eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          break;
330eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai        case IDM_EXIT:
331eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          DestroyWindow(wnd);
332eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          break;
333eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai        case ID_SERVER_START:
334eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          CrashServerStart();
335eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          break;
336eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai        case ID_SERVER_STOP:
337eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          CrashServerStop();
338eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          break;
339eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai        case ID_CLIENT_DEREFZERO:
340eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          DerefZeroCrash();
341eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          break;
342eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai        case ID_CLIENT_INVALIDPARAM:
343eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          InvalidParamCrash();
344eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          break;
345eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai        case ID_CLIENT_PURECALL:
346eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          PureCallCrash();
347eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          break;
348eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai        case ID_CLIENT_REQUESTEXPLICITDUMP:
349eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          RequestDump();
350eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          break;
351eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai        default:
352eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai          return DefWindowProc(wnd, message, w_param, l_param);
353eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      }
354eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      break;
355eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    case WM_CREATE:
356eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      client_status_edit_box = CreateWindow(TEXT("EDIT"),
357eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                            NULL,
358eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                            kEditBoxStyles,
359eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                            0,
360eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                            0,
361eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                            0,
362eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                            0,
363eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                            wnd,
364eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                            NULL,
365eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                            instance,
366eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                            NULL);
367eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      break;
368eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    case WM_SIZE:
369eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      // Make the edit control the size of the window's client area.
370eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      MoveWindow(client_status_edit_box,
371eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                 0,
372eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                 0,
373eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                 LOWORD(l_param),        // width of client area.
374eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                 HIWORD(l_param),        // height of client area.
375eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                 TRUE);                  // repaint window.
376eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      break;
377eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    case WM_SETFOCUS:
378eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      SetFocus(client_status_edit_box);
379eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      break;
380eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    case WM_PAINT:
381eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      hdc = BeginPaint(wnd, &ps);
382eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      EndPaint(wnd, &ps);
383eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      break;
384eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    case WM_DESTROY:
385eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      CleanUp();
386eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      PostQuitMessage(0);
387eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      break;
388eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    default:
389eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      return DefWindowProc(wnd, message, w_param, l_param);
390eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
391eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
392eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  return 0;
393eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
394eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
395eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai// Message handler for about box.
396eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiINT_PTR CALLBACK About(HWND dlg,
397eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                       UINT message,
398eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                       WPARAM w_param,
399eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                       LPARAM l_param) {
400eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  UNREFERENCED_PARAMETER(l_param);
401eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  switch (message) {
402eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    case WM_INITDIALOG:
403eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      return (INT_PTR)TRUE;
404eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
405eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    case WM_COMMAND:
406eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      if (LOWORD(w_param) == IDOK || LOWORD(w_param) == IDCANCEL) {
407eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai        EndDialog(dlg, LOWORD(w_param));
408eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai        return (INT_PTR)TRUE;
409eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      }
410eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      break;
411eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
412eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
413eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  return (INT_PTR)FALSE;
414eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
415eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
416eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}  // namespace google_breakpad
417eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
418eeca9921c563d802cccc5593bf55dcb7683e7250mmentovaiint APIENTRY _tWinMain(HINSTANCE instance,
419eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                       HINSTANCE previous_instance,
420eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                       LPTSTR command_line,
421eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                       int command_show) {
422eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  using namespace google_breakpad;
423eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
424eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  UNREFERENCED_PARAMETER(previous_instance);
425eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  UNREFERENCED_PARAMETER(command_line);
426eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
427eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  cs_edit = new CRITICAL_SECTION();
428eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  InitializeCriticalSection(cs_edit);
429eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
430eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // This is needed for CRT to not show dialog for invalid param
431eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // failures and instead let the code handle it.
432eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  _CrtSetReportMode(_CRT_ASSERT, 0);
433eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  handler = new ExceptionHandler(L"C:\\dumps\\",
434eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                 NULL,
435eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                 google_breakpad::ShowDumpResults,
436eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                 NULL,
437eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                 ExceptionHandler::HANDLER_ALL,
438eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                 MiniDumpNormal,
439eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai                                 kPipeName);
440eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
441eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Initialize global strings.
442eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  LoadString(instance, IDS_APP_TITLE, title, kMaxLoadString);
443eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  LoadString(instance,
444eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai             IDC_CRASHGENERATIONAPP,
445eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai             window_class,
446eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai             kMaxLoadString);
447eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  MyRegisterClass(instance);
448eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
449eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Perform application initialization.
450eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  if (!InitInstance (instance, command_show)) {
451eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    return FALSE;
452eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
453eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
454eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  HACCEL accel_table = LoadAccelerators(
455eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      instance,
456eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      MAKEINTRESOURCE(IDC_CRASHGENERATIONAPP));
457eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
458eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  // Main message loop.
459eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  MSG msg;
460eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  while (GetMessage(&msg, NULL, 0, 0)) {
461eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    if (!TranslateAccelerator(msg.hwnd, accel_table, &msg)) {
462eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      TranslateMessage(&msg);
463eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai      DispatchMessage(&msg);
464eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai    }
465eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  }
466eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
467eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai  return (int)msg.wParam;
468eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai}
469eeca9921c563d802cccc5593bf55dcb7683e7250mmentovai
470