]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
thread-and-timer-corrections-to-afscreds-20031121
authorJeffrey Altman <jaltman@grand.central.org>
Fri, 21 Nov 2003 18:33:10 +0000 (18:33 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Fri, 21 Nov 2003 18:33:10 +0000 (18:33 +0000)
Changes to afscreds to place the obtain tokens dialog into a separate
thread to prevent blocking of the Windows Message queue.  Requires
utilization of mutex semaphores to protect credential data structures.

Previous versions of afscreds would set/unset the timer event every
time the program received an event indicating user activity including
dragging the mouse across the systemtray icon.  This resulted in
extremely unpredictable behavior.  Now the timer event is only turned
off when it must be turned off; and turned on when it must be turned on.
The result is a credential expiration check once a minute.

src/WINNT/client_creds/afscreds.h
src/WINNT/client_creds/creds.cpp
src/WINNT/client_creds/creds.h
src/WINNT/client_creds/credstab.cpp
src/WINNT/client_creds/main.cpp
src/WINNT/client_creds/mounttab.cpp
src/WINNT/client_creds/resource.h
src/WINNT/client_creds/shortcut.cpp
src/WINNT/client_creds/shortcut.h
src/WINNT/client_creds/trayicon.cpp
src/WINNT/client_creds/window.cpp

index 422c8385c79100a2d8641eb748dc841f162e7c55..a2f7999c50ac56f4ec70e80937ee5ccc32188081 100644 (file)
 #include <time.h>
 #include <shellapi.h>
 #include <WINNT/al_wizard.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <osithrdnt.h>
+#include <osisleep.h>
+#include <osibasel.h>
+#ifdef __cplusplus
+}
+#endif
 #include "resource.h"
 #include "checklist.h"
 #include "window.h"
@@ -79,6 +88,8 @@ typedef struct
    BOOL fStartup;
    BOOL fIsWinNT;
    TCHAR szHelpFile[ MAX_PATH ];
+   osi_mutex_t expirationCheckLock;
+   osi_mutex_t credsLock;
    } GLOBALS;
 
 extern GLOBALS g;
@@ -89,7 +100,7 @@ extern GLOBALS g;
  *
  */
 
-#define cminREMIND_TEST      3    // test every minute for expired creds
+#define cminREMIND_TEST      1    // test every minute for expired creds
 #define cminREMIND_WARN      15   // warn if creds expire in 15 minutes
 
 #define cmsecMOUSEOVER       1000 // retest freq when mouse is over tray icon
index 0f3956c35db561dbe31ad0bd7c8d572bfad781e9..994b73c8f9ec7bad9a32a7cee2137b42052b4b88 100644 (file)
@@ -177,10 +177,12 @@ BOOL IsServiceRunning (void)
             {
             QueryServiceStatus (hService, &Status);
             CloseServiceHandle (hService);
-            }
+            } else if ( IsDebuggerPresent() )
+                OutputDebugString("Unable to open Transarc AFS Daemon Service\n");
 
          CloseServiceHandle (hManager);
-         }
+         } else if ( IsDebuggerPresent() )
+             OutputDebugString("Unable to open SC Manager\n");
 
       return (Status.dwCurrentState == SERVICE_RUNNING);
       }
@@ -251,6 +253,8 @@ int GetCurrentCredentials (void)
 {
    int rc = KTC_NOCM;
 
+   lock_ObtainMutex(&g.credsLock);
+
    // Free any knowledge we currently have about the user's credentials
    //
    if (g.aCreds)
@@ -324,6 +328,8 @@ int GetCurrentCredentials (void)
          }
       }
 
+   lock_ReleaseMutex(&g.credsLock);
+
    // We've finished updating g.aCreds. Update the tray icon to reflect
    // whether the user currently has any credentials at all, and
    // re-enable the Remind timer.
index 5d42ad7e19f35cdfbf9cfd1e0fbd778f890116e6..ab87b647a6cacead6185c59d9a884c21bd6a9dea 100644 (file)
@@ -10,6 +10,9 @@
 #ifndef CREDS_H
 #define CREDS_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /*
  * PROTOTYPES _________________________________________________________________
@@ -33,6 +36,8 @@ void GetGatewayName (LPTSTR pszGateway);
 BOOL Creds_OpenLibraries (void);
 void Creds_CloseLibraries (void);
 
-
+#ifdef __cplusplus
+}
+#endif
 #endif
 
index dbcfe8241ac6f39586048792472c08aa40c7b331..bbcb8a63e94af152d2d794a98af3664176481e3b 100644 (file)
@@ -89,6 +89,7 @@ BOOL CALLBACK Creds_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
 void Creds_OnCheckRemind (HWND hDlg)
 {
    LPTSTR pszCell = (LPTSTR)GetWindowLong (hDlg, DWL_USER);
+   lock_ObtainMutex(&g.credsLock);
    for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
       {
       if (!lstrcmpi (g.aCreds[ iCreds ].szCell, pszCell))
@@ -100,6 +101,7 @@ void Creds_OnCheckRemind (HWND hDlg)
       g.aCreds[ iCreds ].fRemind = IsDlgButtonChecked (hDlg, IDC_CREDS_REMIND);
       SaveRemind (iCreds);
       }
+   lock_ReleaseMutex(&g.credsLock);
 }
 
 
@@ -115,6 +117,7 @@ void Creds_OnUpdate (HWND hDlg)
       return;
       }
 
+   lock_ObtainMutex(&g.credsLock);
    for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
       {
       if (!lstrcmpi (g.aCreds[ iCreds ].szCell, pszCell))
@@ -162,6 +165,7 @@ void Creds_OnUpdate (HWND hDlg)
       FreeString (pszCreds);
       }
 
+   lock_ReleaseMutex(&g.credsLock);
    CheckDlgButton (hDlg, IDC_CREDS_REMIND, (iCreds == g.cCreds) ? FALSE : g.aCreds[iCreds].fRemind);
 
    EnableWindow (GetDlgItem (hDlg, IDC_CREDS_OBTAIN), IsServiceRunning());
@@ -191,18 +195,41 @@ void Creds_OnClickDestroy (HWND hDlg)
 }
 
 
-void ShowObtainCreds (BOOL fExpiring, LPTSTR pszCell)
+struct _obtaincreds {
+    DWORD type;
+    HWND  parent;
+    char * cell;
+};
+
+void ObtainCredsThread(void * data)
 {
-   HWND hParent = (IsWindowVisible (g.hMain)) ? g.hMain : NULL;
+    struct _obtaincreds * oc = (struct _obtaincreds *)data;
 
-   if (fExpiring)
-      {
-      ModalDialogParam (IDD_NEWCREDS_EXPIRE, hParent, (DLGPROC)NewCreds_DlgProc, (LPARAM)pszCell);
-      }
-   else // (!fExpiring)
-      {
-      ModalDialogParam (IDD_NEWCREDS, hParent, (DLGPROC)NewCreds_DlgProc, (LPARAM)pszCell);
-      }
+    ModalDialogParam (oc->type, oc->parent, (DLGPROC)NewCreds_DlgProc, (LPARAM)oc->cell);
+    free(oc->cell);
+    free(oc);
+}
+
+void ShowObtainCreds (BOOL fExpiring, LPTSTR pszCell)
+{
+    struct _obtaincreds * oc = (struct _obtaincreds *)malloc(sizeof(struct _obtaincreds));
+    if ( !oc )
+        return;
+    oc->parent = (IsWindowVisible (g.hMain)) ? g.hMain : NULL;
+    oc->type = fExpiring ? IDD_NEWCREDS_EXPIRE : IDD_NEWCREDS;
+    oc->cell = _strdup(pszCell);
+
+    HANDLE thread = 0;
+    ULONG  threadID = 123;
+
+    thread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)ObtainCredsThread,
+                                    oc, 0, &threadID);
+    if (thread != NULL)
+        CloseHandle(thread);
+       else {
+               free(oc->cell);
+               free(oc);
+       }
 }
 
 
@@ -217,7 +244,6 @@ BOOL CALLBACK NewCreds_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
 
       case WM_DESTROY:
          InterlockedDecrement (&g.fShowingMessage);
-         Main_EnableRemindTimer (TRUE);
          break;
 
       case WM_COMMAND:
@@ -278,6 +304,7 @@ void NewCreds_OnInitDialog (HWND hDlg)
       SetDlgItemText (hDlg, IDC_NEWCREDS_CELL, szCell);
       }
 
+   lock_ObtainMutex(&g.credsLock);
    for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
       {
       if (*pszCell && !lstrcmpi (g.aCreds[ iCreds ].szCell, pszCell))
@@ -292,8 +319,10 @@ void NewCreds_OnInitDialog (HWND hDlg)
       SetDlgItemText (hDlg, IDC_NEWCREDS_USER, g.aCreds[ iCreds ].szUser);
       PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem (hDlg, IDC_NEWCREDS_PASSWORD), TRUE);
       }
+   lock_ReleaseMutex(&g.credsLock);
 
    NewCreds_OnEnable (hDlg);
+   SetForegroundWindow(hDlg);
    KillTimer (g.hMain, ID_SERVICE_TIMER);
 }
 
@@ -345,9 +374,21 @@ BOOL NewCreds_OnOK (HWND hDlg)
 
 void NewCreds_OnCancel (HWND hDlg)
 {
-   LPTSTR pszCell = (LPTSTR)GetWindowLong (hDlg, DWL_USER);
+   TCHAR szText[ cchRESOURCE ] = "";
+   LPTSTR pszCell = NULL;
+
+   if (GetDlgItem (hDlg, IDC_NEWCREDS_CELL))
+   {
+       GetDlgItemText (hDlg, IDC_NEWCREDS_CELL, szText, cchRESOURCE);
+       if ( szText[0] )
+           pszCell = szText;
+   }
+
+   if ( !pszCell )
+       pszCell = (LPTSTR)GetWindowLong (hDlg, DWL_USER);
    if (pszCell)
       {
+      lock_ObtainMutex(&g.credsLock);
       for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
          {
          if (!lstrcmpi (g.aCreds[ iCreds ].szCell, pszCell))
@@ -367,6 +408,7 @@ void NewCreds_OnCancel (HWND hDlg)
                }
             }
          }
+      lock_ReleaseMutex(&g.credsLock);
       }
 }
 
index 2cafd0c90b4cf80ef0857a086df0d71ff30c5757..a4bc850455f5c2e89912a37fa9e3ea2510c897c1 100644 (file)
@@ -127,18 +127,8 @@ BOOL InitApp (LPSTR pszCmdLineA)
                         break;
          case 'x':
          case 'X':
-            DWORD LogonOption;
-            DWORD LSPtype, LSPsize;
-            HKEY NPKey;
-            LSPsize=sizeof(LogonOption);
-            (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CLIENT_PROVIDER_KEY,
-                                0, KEY_QUERY_VALUE, &NPKey);
-            RegQueryValueEx(NPKey, "LogonOptions", NULL,
-                             &LSPtype, (LPBYTE)&LogonOption, &LSPsize);
-            RegCloseKey (NPKey);
-            if (ISHIGHSECURITY(LogonOption))
-                DoMapShare();
-            GlobalMountDrive();
+             TestAndDoMapShare(SERVICE_START_PENDING);
+             TestAndDoMapShare(SERVICE_RUNNING);
             return 0;
          }
 
@@ -225,6 +215,23 @@ BOOL InitApp (LPSTR pszCmdLineA)
 
    InitCommonControls();
    RegisterCheckListClass();
+   osi_Init();
+   lock_InitializeMutex(&g.expirationCheckLock, "expiration check lock");
+   lock_InitializeMutex(&g.credsLock, "global creds lock");
+
+   if ( IsDebuggerPresent() ) {
+       if ( !g.fIsWinNT )
+           OutputDebugString("No Service Present on non-NT systems\n");
+       else {
+           if ( IsServiceRunning() )
+               OutputDebugString("AFSD Service started\n");
+           else {
+               OutputDebugString("AFSD Service stopped\n");
+               if ( !IsServiceConfigured() )
+                   OutputDebugString("AFSD Service not configured\n");
+           }   
+       }
+   }
 
    // Create a main window. All further initialization will be done during
    // processing of WM_INITDIALOG.
@@ -253,12 +260,16 @@ BOOL InitApp (LPSTR pszCmdLineA)
       else if (!IsServerInstalled())
          Message (MB_ICONHAND, IDS_UNCONFIG_TITLE, IDS_UNCONFIG_DESC);
       }
-   if (IsServiceRunning() && fShow)
+   if (IsServiceRunning()) { 
+      if (fShow)
       {
+      if ( IsDebuggerPresent() )
+          OutputDebugString("Displaying Main window\n");
       Main_Show (TRUE);
       }
-
-   return TRUE;
+   } else if ( IsDebuggerPresent() )
+      OutputDebugString("Displaying Main window\n");
+    return TRUE;
 }
 
 
index 4694deb6be99cd50c7292a2ddb87a09253db3890..b583ba4b3b39f69d720800e02f1f389054ccea83 100644 (file)
@@ -115,6 +115,7 @@ void Mount_OnInitDialog (HWND hDlg)
 void Mount_OnUpdate (HWND hDlg, BOOL fOnInitDialog)
 {
    DRIVEMAPLIST List;
+   memset(&List, 0, sizeof(DRIVEMAPLIST));
    QueryDriveMapList (&List);
 
    HWND hList = GetDlgItem (hDlg, IDC_LIST);
index 4cc3cc9db8553663d5501300cc035569a77a8c61..16b73ead4a5a56b6f8ea07176cd6a2e8a8a8b2e2 100644 (file)
@@ -83,6 +83,7 @@
 #define IDD_WIZ_FINISH                  119
 #define IDD_MAPPING                     120
 #define IDD_TERMINATE_SMALL_95          121
+#define IDD_AUTH                        122
 #define M_TERMINATE                     3000
 #define M_ACTIVATE                      3001
 #define M_REMIND                        3002
index cb0123d0b35dd35e0b99e8bf2d7509c285c0efc2..bbb1a64fd6580834017d20afb2c8899e1451ad0e 100644 (file)
@@ -16,6 +16,7 @@ extern "C" {
 #include <initguid.h>
 #include <windows.h>
 #include <windowsx.h>
+#undef INITGUID
 #include <shlobj.h>
 #include <shellapi.h>
 #include <shobjidl.h>
@@ -40,7 +41,7 @@ void Shortcut_Exit (void)
 }
 
 
-BOOL Shortcut_Create (LPTSTR pszTarget, LPCTSTR pszSource, LPTSTR pszDesc)
+BOOL Shortcut_Create (LPTSTR pszTarget, LPCTSTR pszSource, LPTSTR pszDesc, LPTSTR pszArgs)
 {
    IShellLink *psl;
    HRESULT rc = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
@@ -56,13 +57,18 @@ BOOL Shortcut_Create (LPTSTR pszTarget, LPCTSTR pszSource, LPTSTR pszDesc)
             rc = psl->SetDescription (pszDesc ? pszDesc : pszSource);
             if (SUCCEEDED (rc))
                {
+               if ( pszArgs )
+                   rc = psl->SetArguments (pszArgs);
+                   if (SUCCEEDED (rc))
+                   {
 #ifdef UNICODE
-               rc = ppf->Save (pszTarget, TRUE);
+                   rc = ppf->Save (pszTarget, TRUE);
 #else
-               WORD wsz[ MAX_PATH ];
-               MultiByteToWideChar (CP_ACP, 0, pszTarget, -1, wsz, MAX_PATH);
-               rc = ppf->Save (wsz, TRUE);
+                   WORD wsz[ MAX_PATH ];
+                   MultiByteToWideChar (CP_ACP, 0, pszTarget, -1, wsz, MAX_PATH);
+                   rc = ppf->Save (wsz, TRUE);
 #endif
+                   }
                }
             }
          ppf->Release ();
@@ -75,7 +81,7 @@ BOOL Shortcut_Create (LPTSTR pszTarget, LPCTSTR pszSource, LPTSTR pszDesc)
 
 void Shortcut_FixStartup (LPCTSTR pszLinkName, BOOL fAutoStart)
 {
-   TCHAR szShortcut[ MAX_PATH ] = TEXT("");
+   TCHAR szShortcut[ MAX_PATH + 10 ] = TEXT("");
 
    HKEY hk;
    if (RegOpenKey (HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"), &hk) == 0)
@@ -104,7 +110,7 @@ void Shortcut_FixStartup (LPCTSTR pszLinkName, BOOL fAutoStart)
 
    if (fAutoStart)
       {
-      Shortcut_Create (szShortcut, szSource);
+      Shortcut_Create (szShortcut, szSource, "Autostart Authentication Agent");
       }
    else // (!g.fAutoStart)
       {
index 12d165e6700819e6c26deea0cee094d50ec2862e..ae82d5de91170159b918407bc9dd8ab8a57e5ba1 100644 (file)
@@ -18,7 +18,7 @@
 
 void Shortcut_Init (void);
 void Shortcut_Exit (void);
-BOOL Shortcut_Create (LPTSTR pszTarget, LPCTSTR pszSource, LPTSTR pszDesc = NULL);
+BOOL Shortcut_Create (LPTSTR pszTarget, LPCTSTR pszSource, LPTSTR pszDesc = NULL, LPTSTR pszArgs = NULL);
 void Shortcut_FixStartup (LPCTSTR pszLinkName, BOOL fAutoStart);
 
 
index 10a4c53c1d5c42ed9c996c3cb520d53c6439077a..c07a846c698181712e0673792f6cc50d1b807622 100644 (file)
@@ -44,7 +44,9 @@ void ChangeTrayIcon (int nim)
       nid.uID = 0;
       nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
       nid.uCallbackMessage = WM_TRAYICON;
+      lock_ObtainMutex(&g.credsLock);
       nid.hIcon = ((g.cCreds != 0) && (iExpired == (size_t)-1)) ? ICON_CREDS_YES : ICON_CREDS_NO;
+      lock_ReleaseMutex(&g.credsLock);
       GetString (nid.szTip, (g.fIsWinNT) ? IDS_TOOLTIP : IDS_TOOLTIP_95);
       Shell_NotifyIcon (nim, &nid);
       }
index 35cf864d0f7845633f833ee0d36f28231772087a..f5e3577af0140fa6800047832d920a9805856e06 100644 (file)
@@ -162,11 +162,13 @@ BOOL CALLBACK Main_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
                   InsertMenu (hmDummy, 0, MF_POPUP, (UINT)hm, NULL);
 
                   BOOL fRemind = FALSE;
+                  lock_ObtainMutex(&g.credsLock);
                   for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
                      {
                      if (g.aCreds[ iCreds ].fRemind)
                         fRemind = TRUE;
                      }
+                  lock_ReleaseMutex(&g.credsLock);
                   CheckMenuItem (hm, M_REMIND, MF_BYCOMMAND | ((fRemind) ? MF_CHECKED : MF_UNCHECKED));
 
                   TrackPopupMenu (GetSubMenu (hmDummy, 0),
@@ -268,6 +270,7 @@ void Main_OnInitDialog (HWND hDlg)
 void Main_OnCheckMenuRemind (void)
 {
    BOOL fRemind = FALSE;
+   lock_ObtainMutex(&g.credsLock);
    for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
       {
       if (g.aCreds[ iCreds ].fRemind)
@@ -283,6 +286,7 @@ void Main_OnCheckMenuRemind (void)
          SaveRemind (iCreds);
          }
       }
+   lock_ReleaseMutex(&g.credsLock);
 
    // Check the active tab, and fix its checkbox if necessary
    //
@@ -297,7 +301,7 @@ void Main_OnCheckMenuRemind (void)
 
    // Make sure the reminder timer is going
    //
-   Main_EnableRemindTimer (TRUE);
+   Main_EnableRemindTimer (fRemind);
 }
 
 
@@ -405,7 +409,6 @@ void Main_RepopulateTabs (BOOL fDestroyInvalid)
 
       if (IsWindowVisible (g.hMain))
          fDestroyInvalid = FALSE;
-      Main_EnableRemindTimer (FALSE);
 
       // First we'll have to look around and see what credentials we currently
       // have. This call just updates g.aCreds[]; it doesn't do anything else.
@@ -424,6 +427,7 @@ void Main_RepopulateTabs (BOOL fDestroyInvalid)
       size_t iTabOut = 0;
 
       size_t nCreds = 0;
+      lock_ObtainMutex(&g.credsLock);
       for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
          {
          if (g.aCreds[ iCreds ].szCell[0])
@@ -471,6 +475,7 @@ void Main_RepopulateTabs (BOOL fDestroyInvalid)
                }
             }
          }
+      lock_ReleaseMutex(&g.credsLock);
 
       if (REALLOC (aTabs, cTabs, 1+iTabOut, cREALLOC_TABS))
          aTabs[ iTabOut++ ] = dwTABPARAM_MOUNT;
@@ -533,7 +538,6 @@ void Main_RepopulateTabs (BOOL fDestroyInvalid)
 
       TabCtrl_SetCurSel (hTab, iTabSel);
       Main_OnSelectTab ();
-      Main_EnableRemindTimer (TRUE);
 
       fInHere = FALSE;
       }
@@ -542,15 +546,23 @@ void Main_RepopulateTabs (BOOL fDestroyInvalid)
 
 void Main_EnableRemindTimer (BOOL fEnable)
 {
-   KillTimer (g.hMain, ID_REMIND_TIMER);
+   static BOOL bEnabled = FALSE;
 
-   if (fEnable)
+   if ( fEnable == FALSE && bEnabled == TRUE ) {
+       KillTimer (g.hMain, ID_REMIND_TIMER);
+       bEnabled = FALSE;
+   } else if ( fEnable == TRUE && bEnabled == FALSE ) {
       SetTimer (g.hMain, ID_REMIND_TIMER, (ULONG)cmsec1MINUTE * cminREMIND_TEST, NULL);
+      bEnabled = TRUE;
+   }
 }
 
 
 size_t Main_FindExpiredCreds (void)
 {
+   size_t retval = (size_t) -1;
+   lock_ObtainMutex(&g.expirationCheckLock);
+   lock_ObtainMutex(&g.credsLock);
    for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
       {
       if (!g.aCreds[ iCreds ].szCell[0])
@@ -574,10 +586,14 @@ size_t Main_FindExpiredCreds (void)
       llExpires /= c100ns1SECOND;
 
       if (llExpires <= (llNow + (LONGLONG)cminREMIND_WARN * csec1MINUTE))
-         return iCreds;
+         retval = (size_t) iCreds;
+         break;
       }
+   
+   lock_ReleaseMutex(&g.credsLock);
+   lock_ReleaseMutex(&g.expirationCheckLock);
 
-   return (size_t)-1;
+   return retval;
 }