windows-server-manager-20050509
[openafs.git] / src / WINNT / afsapplib / al_misc.cpp
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
10 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include <WINNT/afsapplib.h>
16 #include "al_dynlink.h"
17 #include <WINNT/TaAfsAdmSvrClient.h>
18
19
20 /*
21  * DEFINITIONS ________________________________________________________________
22  *
23  */
24
25 #define GWD_ANIMATIONFRAME  TEXT("afsapplib/al_misc.cpp - next animation frame")
26
27
28 /*
29  * PROTOTYPES _________________________________________________________________
30  *
31  */
32
33 BOOL CALLBACK AfsAppLib_TranslateErrorFunc (LPTSTR pszText, ULONG code, LANGID idLanguage);
34
35
36 /*
37  * STARTUP ____________________________________________________________________
38  *
39  */
40
41 static HINSTANCE g_hInst = NULL;
42 static HINSTANCE g_hInstApp = NULL;
43
44 HINSTANCE AfsAppLib_GetInstance (void)
45 {
46    return g_hInst;
47 }
48
49
50 EXPORTED HINSTANCE AfsAppLib_GetAppInstance (void)
51 {
52    if (!g_hInstApp)
53       g_hInstApp = GetModuleHandle(NULL);
54    return g_hInstApp;
55 }
56
57
58 EXPORTED void AfsAppLib_SetAppInstance (HINSTANCE hInst)
59 {
60    g_hInstApp = hInst;
61 }
62
63
64 extern "C" BOOLEAN _stdcall DllEntryPoint (HANDLE hInst, DWORD dwReason, PVOID pReserved)
65 {
66    switch (dwReason)
67       {
68       case DLL_PROCESS_ATTACH:
69          if (!g_hInst)
70             {
71             g_hInst = (HINSTANCE)hInst;
72             TaLocale_LoadCorrespondingModule (g_hInst);
73             SetErrorTranslationFunction ((LPERRORPROC)AfsAppLib_TranslateErrorFunc);
74
75             InitCommonControls();
76             RegisterSpinnerClass();
77             RegisterElapsedClass();
78             RegisterTimeClass();
79             RegisterDateClass();
80             RegisterSockAddrClass();
81             RegisterCheckListClass();
82             RegisterFastListClass();
83             }
84          break;
85       }
86    return TRUE;
87 }
88
89
90 /*
91  * IMAGE LISTS ________________________________________________________________
92  *
93  */
94
95 HIMAGELIST AfsAppLib_CreateImageList (BOOL fLarge)
96 {
97    HIMAGELIST hil;
98    hil = ImageList_Create ((fLarge)?32:16, (fLarge)?32:16, TRUE, 4, 0);
99
100    AfsAppLib_AddToImageList (hil, IDI_SERVER,           fLarge);
101    AfsAppLib_AddToImageList (hil, IDI_SERVER_ALERT,     fLarge);
102    AfsAppLib_AddToImageList (hil, IDI_SERVER_UNMON,     fLarge);
103    AfsAppLib_AddToImageList (hil, IDI_SERVICE,          fLarge);
104    AfsAppLib_AddToImageList (hil, IDI_SERVICE_ALERT,    fLarge);
105    AfsAppLib_AddToImageList (hil, IDI_SERVICE_STOPPED,  fLarge);
106    AfsAppLib_AddToImageList (hil, IDI_AGGREGATE,        fLarge);
107    AfsAppLib_AddToImageList (hil, IDI_AGGREGATE_ALERT,  fLarge);
108    AfsAppLib_AddToImageList (hil, IDI_FILESET,          fLarge);
109    AfsAppLib_AddToImageList (hil, IDI_FILESET_ALERT,    fLarge);
110    AfsAppLib_AddToImageList (hil, IDI_FILESET_LOCKED,   fLarge);
111    AfsAppLib_AddToImageList (hil, IDI_BOSSERVICE,       fLarge);
112    AfsAppLib_AddToImageList (hil, IDI_CELL,             fLarge);
113    AfsAppLib_AddToImageList (hil, IDI_SERVER_KEY,       fLarge);
114    AfsAppLib_AddToImageList (hil, IDI_USER,             fLarge);
115    AfsAppLib_AddToImageList (hil, IDI_GROUP,            fLarge);
116
117    return hil;
118 }
119
120
121 void AfsAppLib_AddToImageList (HIMAGELIST hil, int idi, BOOL fLarge)
122 {
123    HICON hi = TaLocale_LoadIcon (idi);
124    ImageList_AddIcon (hil, hi);
125 }
126
127
128 /*
129  * ANIMATION __________________________________________________________________
130  *
131  */
132
133 void AfsAppLib_AnimateIcon (HWND hIcon, int *piFrameLast)
134 {
135    static HICON hiStop;
136    static HICON hiFrame[8];
137    static BOOL fLoaded = FALSE;
138
139    if (!fLoaded)
140       {
141       hiStop     = TaLocale_LoadIcon (IDI_SPINSTOP);
142       hiFrame[0] = TaLocale_LoadIcon (IDI_SPIN1);
143       hiFrame[1] = TaLocale_LoadIcon (IDI_SPIN2);
144       hiFrame[2] = TaLocale_LoadIcon (IDI_SPIN3);
145       hiFrame[3] = TaLocale_LoadIcon (IDI_SPIN4);
146       hiFrame[4] = TaLocale_LoadIcon (IDI_SPIN5);
147       hiFrame[5] = TaLocale_LoadIcon (IDI_SPIN6);
148       hiFrame[6] = TaLocale_LoadIcon (IDI_SPIN7);
149       hiFrame[7] = TaLocale_LoadIcon (IDI_SPIN8);
150       fLoaded = TRUE;
151       }
152
153    if (piFrameLast)
154       {
155       *piFrameLast = (*piFrameLast == 7) ? 0 : (1+*piFrameLast);
156       }
157
158    SendMessage (hIcon, STM_SETICON, (WPARAM)((piFrameLast) ? hiFrame[ *piFrameLast ] : hiStop), 0);
159 }
160
161
162 BOOL CALLBACK AnimationHook (HWND hIcon, UINT msg, WPARAM wp, LPARAM lp)
163 {
164    PVOID oldProc = Subclass_FindNextHook (hIcon, AnimationHook);
165
166    switch (msg)
167       {
168       case WM_TIMER:
169          int iFrame;
170          iFrame = GetWindowData (hIcon, GWD_ANIMATIONFRAME);
171          AfsAppLib_AnimateIcon (hIcon, &iFrame);
172          SetWindowData (hIcon, GWD_ANIMATIONFRAME, iFrame);
173          break;
174
175       case WM_DESTROY:
176          Subclass_RemoveHook (hIcon, AnimationHook);
177          break;
178       }
179
180    if (oldProc)
181       return CallWindowProc ((WNDPROC)oldProc, hIcon, msg, wp, lp);
182    else
183       return DefWindowProc (hIcon, msg, wp, lp);
184 }
185
186
187 void AfsAppLib_StartAnimation (HWND hIcon, int fps)
188 {
189    Subclass_AddHook (hIcon, AnimationHook);
190    SetTimer (hIcon, 0, 1000/((fps) ? fps : 8), NULL);
191    AfsAppLib_AnimateIcon (hIcon);
192 }
193
194
195 void AfsAppLib_StopAnimation (HWND hIcon)
196 {
197    KillTimer (hIcon, 0);
198    AfsAppLib_AnimateIcon (hIcon);
199    Subclass_RemoveHook (hIcon, AnimationHook);
200 }
201
202
203 /*
204  * ERROR TRANSLATION __________________________________________________________
205  *
206  */
207
208 BOOL CALLBACK AfsAppLib_TranslateErrorFunc (LPTSTR pszText, ULONG code, LANGID idLanguage)
209 {
210    DWORD idClient;
211    if ((idClient = AfsAppLib_GetAdminServerClientID()) != 0)
212       {
213       ULONG status;
214       return asc_ErrorCodeTranslate (idClient, code, idLanguage, pszText, &status);
215       }
216    else
217        if (OpenUtilLibrary())
218       {
219       const char *pszTextA = NULL;
220       afs_status_t status;
221       if (util_AdminErrorCodeTranslate (code, idLanguage, &pszTextA, &status) && (pszTextA))
222          {
223          CopyAnsiToString (pszText, pszTextA);
224          return TRUE;
225          }
226       CloseUtilLibrary();
227       }
228
229    return FALSE;
230 }
231
232
233 BOOL AfsAppLib_TranslateError (LPTSTR pszText, ULONG status, LANGID idLanguage)
234 {
235    LANGID idLangOld = TaLocale_GetLanguage();
236    TaLocale_SetLanguage (idLanguage);
237
238    BOOL rc = FormatError (pszText, TEXT("%s"), status);
239
240    TaLocale_SetLanguage (idLangOld);
241    return rc;
242 }
243
244
245 /*
246  * CELL LIST __________________________________________________________________
247  *
248  */
249
250 #define cREALLOC_CELLLIST   4
251
252 LPCELLLIST AfsAppLib_GetCellList (HKEY hkBase, LPTSTR pszRegPath)
253 {
254    LPCELLLIST lpcl = New (CELLLIST);
255    memset (lpcl, 0x00, sizeof(CELLLIST));
256
257    if (hkBase && pszRegPath)
258       {
259       lpcl->hkBase = hkBase;
260       lstrcpy (lpcl->szRegPath, pszRegPath);
261
262       HKEY hk;
263       if (RegOpenKey (hkBase, pszRegPath, &hk) == 0)
264          {
265          TCHAR szCell[ cchNAME ];
266          for (size_t ii = 0; RegEnumKey (hk, ii, szCell, cchNAME) == 0; ++ii)
267             {
268             if (REALLOC (lpcl->aCells, lpcl->nCells, 1+ii, cREALLOC_CELLLIST))
269                {
270                lpcl->aCells[ ii ] = CloneString (szCell);
271                }
272             }
273          RegCloseKey (hk);
274          }
275       }
276    else // Get cell list from AFS
277       {
278       // TODO
279       }
280
281    TCHAR szDefCell[ cchNAME ];
282    if (AfsAppLib_GetLocalCell (szDefCell))
283       {
284       for (size_t iclDef = 0; iclDef < lpcl->nCells; ++iclDef)
285          {
286          if (lpcl->aCells[ iclDef ] == NULL)
287             continue;
288          if (!lstrcmpi (lpcl->aCells[ iclDef ], szDefCell))
289             break;
290          }
291       if (iclDef == lpcl->nCells) // default cell not currently in list?
292          {
293          for (iclDef = 0; iclDef < lpcl->nCells; ++iclDef)
294             {
295             if (lpcl->aCells[ iclDef ] == NULL)
296                break;
297             }
298          if (REALLOC (lpcl->aCells, lpcl->nCells, 1+iclDef, cREALLOC_CELLLIST))
299             {
300             lpcl->aCells[iclDef] = CloneString (szDefCell);
301             }
302          }
303       if ((iclDef > 0) && (iclDef < lpcl->nCells) && (lpcl->aCells[ iclDef ]))
304          {
305          LPTSTR pszZero = lpcl->aCells[0];
306          lpcl->aCells[0] = lpcl->aCells[iclDef];
307          lpcl->aCells[iclDef] = pszZero;
308          }
309       }
310
311    for ( ; (lpcl->nCells != 0); (lpcl->nCells)--)
312       {
313       if (lpcl->aCells[ lpcl->nCells-1 ] != NULL)
314          break;
315       }
316
317    return lpcl;
318 }
319
320
321 LPCELLLIST AfsAppLib_GetCellList (LPCELLLIST lpclCopy)
322 {
323    LPCELLLIST lpcl = New (CELLLIST);
324    memset (lpcl, 0x00, sizeof(CELLLIST));
325
326    if (lpclCopy)
327       {
328       if (REALLOC (lpcl->aCells, lpcl->nCells, lpclCopy->nCells, cREALLOC_CELLLIST))
329          {
330          for (size_t icl = 0; icl < lpcl->nCells; ++icl)
331             {
332             if (lpclCopy->aCells[ icl ])
333                {
334                lpcl->aCells[ icl ] = CloneString (lpclCopy->aCells[ icl ]);
335                }
336             }
337          }
338       }
339
340    return lpcl;
341 }
342
343
344 void AfsAppLib_AddToCellList (LPCELLLIST lpcl, LPTSTR pszCell)
345 {
346    if (lpcl && lpcl->hkBase && lpcl->szRegPath[0])
347       {
348       TCHAR szPath[ MAX_PATH ];
349       wsprintf (szPath, TEXT("%s\\%s"), lpcl->szRegPath, pszCell);
350
351       HKEY hk;
352       if (RegCreateKey (lpcl->hkBase, szPath, &hk) == 0)
353          {
354          RegCloseKey (hk);
355          }
356       }
357 }
358
359
360 void AfsAppLib_FreeCellList (LPCELLLIST lpcl)
361 {
362    if (lpcl)
363       {
364       if (lpcl->aCells)
365          {
366          for (size_t icl = 0; icl < lpcl->nCells; ++icl)
367             {
368             if (lpcl->aCells[icl] != NULL)
369                FreeString (lpcl->aCells[icl]);
370             }
371          Free (lpcl->aCells);
372          }
373       Delete (lpcl);
374       }
375 }
376
377
378 /*
379  * TRULY MISCELLANEOUS ________________________________________________________
380  *
381  */
382
383 BOOL AfsAppLib_IsTimeInFuture (LPSYSTEMTIME pstTest)
384 {
385    SYSTEMTIME stNow;
386    GetSystemTime (&stNow);
387
388    FILETIME ftNowGMT;
389    SystemTimeToFileTime (&stNow, &ftNowGMT);
390
391    FILETIME ftTest;
392    SystemTimeToFileTime (pstTest, &ftTest);
393
394    if (CompareFileTime (&ftTest, &ftNowGMT) >= 0)
395       return TRUE;
396
397    return FALSE;
398 }
399
400
401 void AfsAppLib_UnixTimeToSystemTime (LPSYSTEMTIME pst, ULONG ut, BOOL fElapsed)
402 {
403    // A Unix time is the number of seconds since 1/1/1970.
404    // The first step in this conversion is to change that count-of-seconds
405    // into a count-of-100ns-intervals...
406    //
407    LARGE_INTEGER ldw;
408    ldw.QuadPart = (LONGLONG)10000000 * (LONGLONG)ut;
409
410    // Then adjust the count to be a count-of-100ns-intervals since
411    // 1/1/1601, instead of 1/1/1970. That means adding a *big* number...
412    //
413    ldw.QuadPart += (LONGLONG)0x019db1ded53e8000;
414
415    // Now the count is effectively a FILETIME, which we can convert
416    // to a SYSTEMTIME with a Win32 API.
417    //
418    FILETIME ft;
419    ft.dwHighDateTime = (DWORD)ldw.HighPart;
420    ft.dwLowDateTime = (DWORD)ldw.LowPart;
421    FileTimeToSystemTime (&ft, pst);
422
423    if (fElapsed)
424       {
425       pst->wYear -= 1970;
426       pst->wMonth -= 1;
427       pst->wDayOfWeek -= 1;
428       pst->wDay -= 1;
429       }
430 }
431
432
433 void AfsAppLib_SplitCredentials (LPTSTR pszCreds, LPTSTR pszCell, LPTSTR pszID)
434 {
435    LPTSTR pszSlash = (LPTSTR)lstrrchr (pszCreds, TEXT('/'));
436    if (pszSlash == NULL)
437       {
438       if (pszCell)
439          AfsAppLib_GetLocalCell (pszCell);
440       if (pszID)
441          lstrcpy (pszID, pszCreds);
442       }
443    else // a cell was specified
444       {
445       if (pszCell)
446          lstrzcpy (pszCell, pszCreds, pszSlash -pszCreds);
447       if (pszID)
448          lstrcpy (pszID, 1+pszSlash);
449       }
450 }
451
452
453 BOOL AfsAppLib_GetLocalCell (LPTSTR pszCell, ULONG *pStatus)
454 {
455    static TCHAR szCell[ cchRESOURCE ] = TEXT("");
456
457    BOOL rc = TRUE;
458    ULONG status = 0;    
459
460    if (szCell[0] == TEXT('\0'))
461       {
462       DWORD idClient;
463       if ((idClient = AfsAppLib_GetAdminServerClientID()) != 0)
464          {
465          rc = asc_LocalCellGet (idClient, szCell, &status);
466          }
467       else 
468           if (OpenClientLibrary())
469          {
470          char szCellNameA[ MAX_PATH ];
471          if ((rc = afsclient_LocalCellGet (szCellNameA, (afs_status_p)&status)) == TRUE)
472             {
473             CopyAnsiToString (szCell, szCellNameA);
474             }
475          CloseClientLibrary();
476          }
477       }
478
479    if (rc)
480       lstrcpy (pszCell, szCell);
481    else if (pStatus)
482       *pStatus = status;
483    return rc;
484 }
485
486
487 BOOL AfsAppLib_ReallocFunction (LPVOID *ppTarget, size_t cbElement, size_t *pcTarget, size_t cReq, size_t cInc)
488 {
489    LPVOID pNew;
490    size_t cNew;
491
492    if (cReq <= *pcTarget)
493       return TRUE;
494
495    if ((cNew = cInc * ((cReq + cInc-1) / cInc)) <= 0)
496       return FALSE;
497
498    if ((pNew = (LPVOID)Allocate (cbElement * cNew)) == NULL)
499       return FALSE;
500    memset (pNew, 0x00, cbElement * cNew);
501
502    if (*pcTarget != 0)
503       {
504       memcpy (pNew, *ppTarget, cbElement * (*pcTarget));
505       Free (*ppTarget);
506       }
507
508    *ppTarget = pNew;
509    *pcTarget = cNew;
510    return TRUE;
511 }
512
513
514 HFONT AfsAppLib_CreateFont (int idsFont)
515 {
516    TCHAR szFont[ cchRESOURCE ];
517    GetString (szFont, idsFont);
518
519    HFONT hf = (HFONT)GetStockObject (DEFAULT_GUI_FONT);
520
521    LOGFONT lf;
522    GetObject (hf, sizeof(lf), &lf);
523    lf.lfWeight = FW_NORMAL;
524
525    LPTSTR pszSection = szFont;
526    LPTSTR pszNextSection;
527    if ((pszNextSection = (LPTSTR)lstrchr (pszSection, TEXT(','))) != NULL)
528       *pszNextSection++ = TEXT('\0');
529    if (!pszSection || !*pszSection)
530       return NULL;
531
532    lstrcpy (lf.lfFaceName, pszSection);
533
534    pszSection = pszNextSection;
535    if ((pszNextSection = (LPTSTR)lstrchr (pszSection, TEXT(','))) != NULL)
536       *pszNextSection++ = TEXT('\0');
537    if (!pszSection || !*pszSection)
538       return NULL;
539
540    HDC hdc = GetDC (NULL);
541    lf.lfHeight = -MulDiv (_ttol(pszSection), GetDeviceCaps (hdc, LOGPIXELSY), 72);
542    ReleaseDC (NULL, hdc);
543
544    pszSection = pszNextSection;
545    if ((pszNextSection = (LPTSTR)lstrchr (pszSection, TEXT(','))) != NULL)
546       *pszNextSection++ = TEXT('\0');
547    if (pszSection && *pszSection)
548       {
549       if (lstrchr (pszSection, TEXT('b')) || lstrchr (pszSection, TEXT('B')))
550          lf.lfWeight = FW_BOLD;
551       if (lstrchr (pszSection, TEXT('i')) || lstrchr (pszSection, TEXT('I')))
552          lf.lfItalic = TRUE;
553       if (lstrchr (pszSection, TEXT('u')) || lstrchr (pszSection, TEXT('U')))
554          lf.lfUnderline = TRUE;
555       }
556
557    return CreateFontIndirect(&lf);
558 }
559