windows-afsifs-20050620
[openafs.git] / src / WINNT / afsd / afsd.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9 /* AFSIFS Portions copyright (c) 2005
10  * the regents of the university of michigan
11  * all rights reserved
12  * 
13  * permission is granted to use, copy, create derivative works and
14  * redistribute this software and such derivative works for any purpose,
15  * so long as the name of the university of michigan is not used in
16  * any advertising or publicity pertaining to the use or distribution
17  * of this software without specific, written prior authorization.  if
18  * the above copyright notice or any other identification of the
19  * university of michigan is included in any copy of any portion of
20  * this software, then the disclaimer below must also be included.
21  * 
22  * this software is provided as is, without representation from the
23  * university of michigan as to its fitness for any purpose, and without
24  * warranty by the university of michigan of any kind, either express 
25  * or implied, including without limitation the implied warranties of
26  * merchantability and fitness for a particular purpose.  the regents
27  * of the university of michigan shall not be liable for any damages,   
28  * including special, indirect, incidental, or consequential damages, 
29  * with respect to any claim arising out or in connection with the use
30  * of the software, even if it has been or is hereafter advised of the
31  * possibility of such damages.
32  */
33
34 #include <afs/param.h>
35 #include <afs/stds.h>
36
37 #include <windows.h>
38 #include <string.h>
39 #include <nb30.h>
40
41 #include <osi.h>
42 #include "afsd.h"
43 #include "afsd_init.h"
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <winsock2.h>
47
48 #ifdef _DEBUG
49 #include <crtdbg.h>
50 #endif
51
52 #include "afsdifs.h"
53
54 HANDLE main_inst;
55 HWND main_wnd;
56 char main_statusText[100];
57 RECT main_rect;
58 osi_log_t *afsd_logp;
59
60 HANDLE hAFSDWorkerThread[WORKER_THREADS], DoTerminate;
61
62 extern int traceOnPanic;
63
64 extern void afsd_DbgBreakAllocInit();
65 extern void afsd_DbgBreakAdd(DWORD requestNumber);
66
67 HANDLE WaitToTerminate = NULL;
68
69 /*
70  * Notifier function for use by osi_panic
71  */
72 void afsd_notifier(char *msgp, char *filep, long line)
73 {
74         char tbuffer[100];
75         if (filep)
76                 sprintf(tbuffer, "Error at file %s, line %d", filep, line);
77         else
78                 strcpy(tbuffer, "Error at unknown location");
79
80         if (!msgp)
81                 msgp = "Assertion failure";
82
83         MessageBox(NULL, tbuffer, msgp, MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
84
85         afsd_ForceTrace(TRUE);
86         buf_ForceTrace(TRUE);
87
88         if (traceOnPanic) {
89                 _asm int 3h;
90         }
91
92         exit(1);
93 }
94
95 /* Init function called when window application starts.  Inits instance and
96  * application together, since in Win32 they're essentially the same.
97  *
98  * Function then goes into a loop handling user interface messages.  Most are
99  * used to handle redrawing the icon.
100  */
101 int WINAPI WinMain(
102         HINSTANCE hInstance,
103         HINSTANCE hPrevInstance,
104         char *lpCmdLine,
105         int nCmdShow)
106 {
107         MSG msg;
108         int i;
109         
110     afsd_SetUnhandledExceptionFilter();
111        
112 #ifdef _DEBUG
113     afsd_DbgBreakAllocInit();
114     _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF /* | _CRTDBG_CHECK_ALWAYS_DF */ | _CRTDBG_CHECK_CRT_DF | _CRTDBG_DELAY_FREE_MEM_DF );
115     if (lpCmdLine)
116     {
117         char *allocRequest = strtok(lpCmdLine, " \t");
118         while (allocRequest)
119         {
120             afsd_DbgBreakAdd(atoi(allocRequest));
121             allocRequest = strtok(NULL, " \t");
122         }
123     }
124 #endif 
125
126     if (!InitClass(hInstance))
127         return (FALSE);
128
129     if (!InitInstance(hInstance, nCmdShow))
130         return (FALSE);
131
132     while (GetMessage(&msg, NULL, 0, 0)) {
133         TranslateMessage(&msg);
134         DispatchMessage(&msg);
135     }
136
137 #ifdef AFSIFS
138     WaitForMultipleObjects(WORKER_THREADS, hAFSDWorkerThread, TRUE, INFINITE);
139     for (i = 0; i < WORKER_THREADS; i++)
140         CloseHandle(hAFSDWorkerThread[i]);
141     //CloseHandle(hAFSDMainThread);
142     RpcMgmtStopServerListening(NULL);
143 #endif
144
145     return (msg.wParam);
146 }
147
148
149 /* create the window type for our main window */
150 BOOL InitClass(HANDLE hInstance)
151 {
152         WNDCLASS  wc;
153
154         wc.style = CS_DBLCLKS;          /* double-click messages */
155         wc.lpfnWndProc = (WNDPROC) MainWndProc;
156         wc.cbClsExtra = 0;
157         wc.cbWndExtra = 0;
158         wc.hInstance = hInstance;
159         wc.hIcon = LoadIcon(hInstance, "AFSDIcon");
160         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
161         wc.hbrBackground = GetStockObject(WHITE_BRUSH); 
162         wc.lpszMenuName =  "AFSDMenu";
163         wc.lpszClassName = "AFSDWinClass";
164
165         return (RegisterClass(&wc));
166 }
167
168 /* initialize the process.  Reads the init files to get the appropriate
169  * information. */
170 BOOL InitInstance(
171         HANDLE hInstance,
172         int nCmdShow)
173 {
174         HWND hWnd;
175         HDC hDC;
176         TEXTMETRIC textmetric;
177         INT nLineHeight;
178     long code, cnt;
179         char *reason;
180  
181         /* remember this, since it is a useful thing for some of the Windows
182          * calls */
183         main_inst = hInstance;
184
185         /* create our window */
186         hWnd = CreateWindow(
187                 "AFSDWinClass",
188                 "AFSD",
189                 WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
190                 CW_USEDEFAULT,
191                 CW_USEDEFAULT,
192                 CW_USEDEFAULT,
193                 CW_USEDEFAULT,
194                 NULL,
195                 NULL,
196                 hInstance,
197                 NULL
198         );
199
200         if (!hWnd)
201                 return (FALSE);
202
203         /* lookup text dimensions */
204         hDC = GetDC(hWnd);
205         GetTextMetrics(hDC, &textmetric);
206         nLineHeight = textmetric.tmExternalLeading + textmetric.tmHeight;
207         
208         main_rect.left   = GetDeviceCaps(hDC, LOGPIXELSX) / 4;   /* 1/4 inch */
209         main_rect.right  = GetDeviceCaps(hDC, HORZRES);
210         main_rect.top    = GetDeviceCaps(hDC, LOGPIXELSY) / 4;   /* 1/4 inch */
211         ReleaseDC(hWnd, hDC);
212         main_rect.bottom = main_rect.top + nLineHeight;
213
214         osi_InitPanic(afsd_notifier);
215
216         afsi_start();
217
218         code = afsd_InitCM(&reason);
219         if (code != 0)
220                 osi_panic(reason, __FILE__, __LINE__);
221
222         code = afsd_InitDaemons(&reason);
223         if (code != 0)
224                 osi_panic(reason, __FILE__, __LINE__);
225
226 #ifndef AFSIFS
227         code = afsd_InitSMB(&reason, MessageBox);
228 #else
229         code = ifs_Init(&reason);
230 #endif
231
232         if (code != 0)
233             osi_panic(reason, __FILE__, __LINE__);
234
235 #ifdef AFSIFS
236         DoTerminate = CreateEvent(NULL, TRUE, FALSE, TEXT("afsd_service_DoTerminate"));
237         if ( GetLastError() == ERROR_ALREADY_EXISTS )
238             afsi_log("Event Object Already Exists: %s", TEXT("afsd_service_DoTerminate"));
239         for (cnt = 0; cnt < WORKER_THREADS; cnt++)
240             hAFSDWorkerThread[cnt] = CreateThread(NULL, 0, ifs_MainLoop, 0, 0, NULL);
241 #endif
242
243         ShowWindow(hWnd, SW_SHOWMINNOACTIVE);
244         UpdateWindow(hWnd);
245         return (TRUE);
246 }
247
248 /* called with no locks with translated messages */
249 LONG APIENTRY MainWndProc(
250         HWND hWnd,
251         unsigned int message,
252         unsigned int wParam,
253         long lParam)
254 {
255         HDC hDC;                         /* display-context variable     */
256         PAINTSTRUCT ps;                  /* paint structure              */
257
258         main_wnd = hWnd;
259
260         switch (message) {
261             case WM_QUERYOPEN:
262                 /* block attempts to open the window */
263                 return 0;
264
265             case WM_COMMAND:
266                 /* LOWORD(wParam) is command */
267                 return (DefWindowProc(hWnd, message, wParam, lParam));
268
269             case WM_CREATE:
270                 break;
271
272             case WM_PAINT:
273                 hDC = BeginPaint (hWnd, &ps);
274                 /* nothing to print, but this clears invalidated rectangle flag */
275                 EndPaint(hWnd, &ps);
276                 break;
277
278             case WM_DESTROY:
279 #ifndef AFSIFS
280                 RpcMgmtStopServerListening(NULL);
281 #else
282                 SetEvent(DoTerminate);
283 #endif
284                 PostQuitMessage(0);
285                 break;
286
287             default:
288                 return (DefWindowProc(hWnd, message, wParam, lParam));
289         }
290         return (0);
291 }