#include "afsd_flushvol.h"
#include "afsd_eventlog.h"
+#include "lanahelper.h"
+
+extern void afsi_log(char *pattern, ...);
static FLUSHVOLTHREADINFO gThreadInfo = {0};
static HANDLE gThreadHandle = NULL;
afs_int32
afsd_ServicePerformFlushVolumeCmd(char *data)
{
- register afs_int32 code;
- struct ViceIoctl blob;
+ register afs_int32 code;
+ struct ViceIoctl blob;
- memset(&blob, '\0', sizeof(blob));
- code = pioctl(data, VIOC_FLUSHVOLUME, &blob, 0);
+ afsi_log("Flushing Volume \"%s\"",data);
+ memset(&blob, '\0', sizeof(blob));
+ code = pioctl(data, VIOC_FLUSHVOLUME, &blob, 0);
- return code;
+ return code;
}
BOOL
afsd_ServicePerformFlushVolumes()
-{
- CONST CHAR COLON = ':';
- CONST CHAR SLASH = '\\';
- CONST DWORD NETRESBUFSIZE = 16384;
- CHAR bufMessage[1024];
- UINT i;
- DWORD dwServerSize;
- DWORD dwRet;
- DWORD dwCount;
- DWORD dwNetResBufSize;
- DWORD dwTotalVols = 0;
- DWORD dwVolBegin, dwVolEnd;
- DWORD dwFlushBegin, dwFlushEnd;
- HANDLE hEnum;
- LPNETRESOURCE lpNetResBuf, lpnr;
- PCHAR pszShareName, pc;
- afs_int32 afsRet = 0;
-
- // Determine the root share name (\\AFS\ALL or \\<machine>-AFS\ALL),
- // and the length of the server name prefix.
- pszShareName = smb_GetSharename();
- if (pszShareName == NULL)
- {
- LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_NO_SHARE_NAME, NULL);
- return FALSE;
- }
- pc = strrchr(pszShareName, SLASH);
- if ((pc == NULL) || ((dwServerSize = pc - pszShareName) < 3))
- {
- LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_BAD_SHARE_NAME,
- pszShareName, NULL);
- free(pszShareName);
- return FALSE;
- }
-
- // Allocate a buffer to hold network resources returned by
- // WNetEnumResource().
- lpNetResBuf = malloc(NETRESBUFSIZE);
- if (lpNetResBuf == NULL)
- {
- // Out of memory, give up now.
- LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_NO_MEMORY, NULL);
- free(pszShareName);
- return FALSE;
- }
-
- // Initialize the flush timer. Note that GetTickCount() returns
- // the number of milliseconds since the system started, in a DWORD,
- // so that the value wraps around every 49.7 days. We do not bother
- // to handle the case where the flush elapsed time is greater than
- // that.
- dwFlushBegin = GetTickCount();
+{
+ CONST CHAR COLON = ':';
+ CONST CHAR SLASH = '\\';
+ CONST DWORD NETRESBUFSIZE = 16384;
+ CHAR bufMessage[1024];
+ UINT i;
+ DWORD dwServerSize;
+ DWORD dwRet;
+ DWORD dwCount;
+ DWORD dwNetResBufSize;
+ DWORD dwTotalVols = 0;
+ DWORD dwVolBegin, dwVolEnd;
+ DWORD dwFlushBegin, dwFlushEnd;
+ HANDLE hEnum;
+ LPNETRESOURCE lpNetResBuf, lpnr;
+ PCHAR pszShareName, pc;
+ afs_int32 afsRet = 0;
+
+ if ( lana_OnlyLoopback() ) {
+ // Nothing to do if we only have a loopback interface
+ return TRUE;
+ }
+
+ // Determine the root share name (\\AFS\ALL or \\<machine>-AFS\ALL),
+ // and the length of the server name prefix.
+ pszShareName = smb_GetSharename();
+ if (pszShareName == NULL)
+ {
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_NO_SHARE_NAME, NULL);
+ return FALSE;
+ }
+ pc = strrchr(pszShareName, SLASH);
+ if ((pc == NULL) || ((dwServerSize = pc - pszShareName) < 3))
+ {
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_BAD_SHARE_NAME,
+ pszShareName, NULL);
+ free(pszShareName);
+ return FALSE;
+ }
+
+ // Allocate a buffer to hold network resources returned by
+ // WNetEnumResource().
+ lpNetResBuf = malloc(NETRESBUFSIZE);
+ if (lpNetResBuf == NULL)
+ {
+ // Out of memory, give up now.
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_NO_MEMORY, NULL);
+ free(pszShareName);
+ return FALSE;
+ }
+
+ // Initialize the flush timer. Note that GetTickCount() returns
+ // the number of milliseconds since the system started, in a DWORD,
+ // so that the value wraps around every 49.7 days. We do not bother
+ // to handle the case where the flush elapsed time is greater than
+ // that.
+ dwFlushBegin = GetTickCount();
+
+ dwRet = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_ANY, 0, NULL,
+ &hEnum);
+ if (dwRet != NO_ERROR)
+ {
+ LogEventMessage(EVENTLOG_ERROR_TYPE, MSG_FLUSH_OPEN_ENUM_ERROR,
+ dwRet);
+ free(pszShareName);
+ return FALSE;
+ }
+
+ // Loop to enumerate network resources, and flush those associated
+ // with AFS volumes.
+ while (1)
+ {
+ dwCount = -1;
+ memset(lpNetResBuf, 0, NETRESBUFSIZE);
+ dwNetResBufSize = NETRESBUFSIZE;
+ dwRet = WNetEnumResource(hEnum, &dwCount,
+ lpNetResBuf, &dwNetResBufSize);
+ if (dwRet != NO_ERROR)
+ break;
+ // Iterate over the returned network resources.
+ for (i = 0, lpnr = lpNetResBuf; i < dwCount; i++, lpnr++)
+ {
+ // Ensure resource has a remote name, and is connected.
+ if ((lpnr->lpRemoteName == NULL) ||
+ (lpnr->dwScope != RESOURCE_CONNECTED))
+ continue;
+ if ((_strnicmp(lpnr->lpRemoteName, pszShareName,
+ dwServerSize) == 0) &&
+ (lpnr->lpRemoteName[dwServerSize] == SLASH))
+ {
+ // got one!
+ // but we don't want to flush '\\[...]afs\all'
+ if (_stricmp(lpnr->lpRemoteName, pszShareName) == 0)
+ continue;
+ ++dwTotalVols;
+
+ dwVolBegin = GetTickCount();
+ afsRet = afsd_ServicePerformFlushVolumeCmd(lpnr->lpRemoteName);
+ dwVolEnd = GetTickCount();
+ if (afsRet == 0)
+ {
+ LogTimingEvent(MSG_TIME_FLUSH_PER_VOLUME,
+ lpnr->lpRemoteName,
+ dwVolEnd - dwVolBegin);
+ }
+ else
+ {
+ LogEvent(EVENTLOG_WARNING_TYPE,
+ MSG_FLUSH_FAILED,
+ lpnr->lpRemoteName, NULL);
+ }
+ }
+ }
+ }
+ WNetCloseEnum(hEnum);
+ free(lpNetResBuf);
+ free(pszShareName);
+ if (dwRet != ERROR_NO_MORE_ITEMS)
+ {
+ LogEventMessage(EVENTLOG_ERROR_TYPE, MSG_FLUSH_ENUM_ERROR,
+ dwRet);
+ return FALSE;
+ }
+
+ dwFlushEnd = GetTickCount();
- dwRet = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_ANY, 0, NULL,
- &hEnum);
- if (dwRet != NO_ERROR)
- {
- LogEventMessage(EVENTLOG_ERROR_TYPE, MSG_FLUSH_OPEN_ENUM_ERROR,
- dwRet);
- free(pszShareName);
- return FALSE;
- }
-
- // Loop to enumerate network resources, and flush those associated
- // with AFS volumes.
- while (1)
- {
- dwCount = -1;
- memset(lpNetResBuf, 0, NETRESBUFSIZE);
- dwNetResBufSize = NETRESBUFSIZE;
- dwRet = WNetEnumResource(hEnum, &dwCount,
- lpNetResBuf, &dwNetResBufSize);
- if (dwRet != NO_ERROR)
- break;
- // Iterate over the returned network resources.
- for (i = 0, lpnr = lpNetResBuf; i < dwCount; i++, lpnr++)
- {
- // Ensure resource has a remote name, and is connected.
- if ((lpnr->lpRemoteName == NULL) ||
- (lpnr->dwScope != RESOURCE_CONNECTED))
- continue;
- if ((_strnicmp(lpnr->lpRemoteName, pszShareName,
- dwServerSize) == 0) &&
- (lpnr->lpRemoteName[dwServerSize] == SLASH))
- {
- // got one!
- // but we don't want to flush '\\[...]afs\all'
- if (_stricmp(lpnr->lpRemoteName,
- pszShareName) == 0)
- continue;
- ++dwTotalVols;
-
- dwVolBegin = GetTickCount();
- afsRet = afsd_ServicePerformFlushVolumeCmd(lpnr->lpRemoteName);
- dwVolEnd = GetTickCount();
- if (afsRet == 0)
- {
- LogTimingEvent(MSG_TIME_FLUSH_PER_VOLUME,
- lpnr->lpRemoteName,
- dwVolEnd - dwVolBegin);
- }
- else
- {
- LogEvent(EVENTLOG_WARNING_TYPE,
- MSG_FLUSH_FAILED,
- lpnr->lpRemoteName, NULL);
- }
- }
- }
- }
- WNetCloseEnum(hEnum);
- free(lpNetResBuf);
- free(pszShareName);
- if (dwRet != ERROR_NO_MORE_ITEMS)
- {
- LogEventMessage(EVENTLOG_ERROR_TYPE, MSG_FLUSH_ENUM_ERROR,
- dwRet);
- return FALSE;
- }
-
- dwFlushEnd = GetTickCount();
-
- // display total volume count in Event Logger
- sprintf(bufMessage, "%d", dwTotalVols);
- LogTimingEvent(MSG_TIME_FLUSH_TOTAL, bufMessage,
- dwFlushEnd - dwFlushBegin);
+ // display total volume count in Event Logger
+ sprintf(bufMessage, "%d", dwTotalVols);
+ LogTimingEvent(MSG_TIME_FLUSH_TOTAL, bufMessage,
+ dwFlushEnd - dwFlushBegin);
- return TRUE;
+ return TRUE;
}
// Report a timing event to the system event log.
static VOID
LogTimingEvent(DWORD dwEventID, LPTSTR lpString1, DWORD dwTime)
{
- CHAR szTime[16];
+ CHAR szTime[16];
- sprintf(szTime, "%lu", dwTime);
- LogEvent(EVENTLOG_INFORMATION_TYPE, dwEventID, lpString1, szTime,
- NULL);
+ sprintf(szTime, "%lu", dwTime);
+ LogEvent(EVENTLOG_INFORMATION_TYPE, dwEventID, lpString1, szTime,
+ NULL);
}
//
HANDLE GetUserToken(DWORD access)
{
- HANDLE hTok = NULL;
- DWORD pid = 0, tid = 0;
-
- // Try it the easy way first - look for a window owned by the shell on
- // our current desktop. If we find one, use that to get the process id.
- HWND shell = FindWindowEx(NULL, NULL, "Progman", NULL);
- if (shell != NULL)
- {
- tid = GetWindowThreadProcessId(shell, &pid);
- }
-
- // We are possibly running on a private window station and desktop: we must
- // switch to the default (which we suppose is where we will find the
- // running shell).
- else
- {
- HWINSTA saveWinSta = GetProcessWindowStation();
- HDESK saveDesk = GetThreadDesktop(GetCurrentThreadId());
- HWINSTA winSta = NULL;
- HDESK desk = NULL;
- BOOL changeFlag = FALSE;
- BOOL dummy = saveWinSta != NULL &&
- saveDesk != NULL &&
- (winSta = OpenWindowStation("WinSta0", FALSE,
- MAXIMUM_ALLOWED)) != NULL &&
- (changeFlag = SetProcessWindowStation(winSta)) != 0 &&
- (desk = OpenDesktop("Default", 0, FALSE,
- MAXIMUM_ALLOWED)) != NULL &&
- SetThreadDesktop(desk) != 0;
-
- // Now find the window and process on this desktop
- shell = FindWindowEx(NULL, NULL, "Progman", NULL);
- if (shell != NULL)
- {
- tid = GetWindowThreadProcessId(shell, &pid);
- }
-
- // Restore our own window station and desktop
- if (changeFlag)
- {
- SetProcessWindowStation(saveWinSta);
- SetThreadDesktop(saveDesk);
- }
-
- // Close temporary objects
- if (winSta != NULL)
- CloseWindowStation(winSta);
- if (desk != NULL)
- CloseDesktop(desk);
- }
-
- //
- // If we have a process id, use that to get the process handle and
- // from there the process' access token.
- //
- if (pid != 0)
- {
- HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
- if (hProc != NULL)
- {
- OpenProcessToken(hProc, access, &hTok) || (hTok = NULL);
- CloseHandle(hProc);
- }
- }
-
- // Return token if we got one
- return hTok;
-}
+ HANDLE hTok = NULL;
+ DWORD pid = 0, tid = 0;
+
+ // Try it the easy way first - look for a window owned by the shell on
+ // our current desktop. If we find one, use that to get the process id.
+ HWND shell = FindWindowEx(NULL, NULL, "Progman", NULL);
+ if (shell != NULL)
+ {
+ tid = GetWindowThreadProcessId(shell, &pid);
+ }
+
+ // We are possibly running on a private window station and desktop: we must
+ // switch to the default (which we suppose is where we will find the
+ // running shell).
+ else
+ {
+ HWINSTA saveWinSta = GetProcessWindowStation();
+ HDESK saveDesk = GetThreadDesktop(GetCurrentThreadId());
+ HWINSTA winSta = NULL;
+ HDESK desk = NULL;
+ BOOL changeFlag = FALSE;
+ BOOL dummy = saveWinSta != NULL &&
+ saveDesk != NULL &&
+ (winSta = OpenWindowStation("WinSta0", FALSE,
+ MAXIMUM_ALLOWED)) != NULL &&
+ (changeFlag = SetProcessWindowStation(winSta)) != 0 &&
+ (desk = OpenDesktop("Default", 0, FALSE,
+ MAXIMUM_ALLOWED)) != NULL &&
+ SetThreadDesktop(desk) != 0;
+
+ // Now find the window and process on this desktop
+ shell = FindWindowEx(NULL, NULL, "Progman", NULL);
+ if (shell != NULL)
+ {
+ tid = GetWindowThreadProcessId(shell, &pid);
+ }
+
+ // Restore our own window station and desktop
+ if (changeFlag)
+ {
+ SetProcessWindowStation(saveWinSta);
+ SetThreadDesktop(saveDesk);
+ }
+
+ // Close temporary objects
+ if (winSta != NULL)
+ CloseWindowStation(winSta);
+ if (desk != NULL)
+ CloseDesktop(desk);
+ }
+
+ //
+ // If we have a process id, use that to get the process handle and
+ // from there the process' access token.
+ //
+ if (pid != 0)
+ {
+ HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
+ if (hProc != NULL)
+ {
+ OpenProcessToken(hProc, access, &hTok) || (hTok = NULL);
+ CloseHandle(hProc);
+ }
+ }
+
+ // Return token if we got one
+ return hTok;
+}
// impersonate logged-on user as client
BOOL
ImpersonateClient()
{
- DWORD dwDesiredAccess = TOKEN_ALL_ACCESS;
- HANDLE hUserToken = GetUserToken(dwDesiredAccess);
+ DWORD dwDesiredAccess = TOKEN_ALL_ACCESS;
+ HANDLE hUserToken = GetUserToken(dwDesiredAccess);
- if (hUserToken == NULL)
- return FALSE;
- if (ImpersonateLoggedOnUser(hUserToken) == 0)
- {
- LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_IMPERSONATE_ERROR,
- NULL);
- return FALSE;
- }
- return TRUE;
+ if (hUserToken == NULL)
+ return FALSE;
+ if (ImpersonateLoggedOnUser(hUserToken) == 0)
+ {
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_IMPERSONATE_ERROR,
+ NULL);
+ return FALSE;
+ }
+ return TRUE;
}
/////////////////////////////////////////////////////////////////////
DWORD WINAPI
afsd_ServiceFlushVolumesThreadProc(LPVOID lpParam)
{
- FLUSHVOLTHREADINFO ThreadInfo;
- PFLUSHVOLTHREADINFO pThreadInfo = (PFLUSHVOLTHREADINFO) lpParam;
- HANDLE arHandles[2] = {0};
- DWORD dwWaitState = 0;
-
- // thread running - get handles
- ThreadInfo.hEventPowerEvent = pThreadInfo->hEventPowerEvent;
- ThreadInfo.hEventResumeMain = pThreadInfo->hEventResumeMain;
- ThreadInfo.hEventTerminate = pThreadInfo->hEventTerminate;
-
- // setup to wait
- arHandles[0] = ThreadInfo.hEventTerminate;
- arHandles[1] = ThreadInfo.hEventPowerEvent;
-
- // do stuff ..
- while (1)
- {
- // wait for an event to happen
- dwWaitState = WaitForMultipleObjectsEx(2, arHandles, FALSE, INFINITE, FALSE);
-
- switch (dwWaitState)
- {
- case WAIT_OBJECT_0:
- // termination signaled
- RevertToSelf();
+ FLUSHVOLTHREADINFO ThreadInfo;
+ PFLUSHVOLTHREADINFO pThreadInfo = (PFLUSHVOLTHREADINFO) lpParam;
+ HANDLE arHandles[2] = {0};
+ DWORD dwWaitState = 0;
+
+ // thread running - get handles
+ ThreadInfo.hEventPowerEvent = pThreadInfo->hEventPowerEvent;
+ ThreadInfo.hEventResumeMain = pThreadInfo->hEventResumeMain;
+ ThreadInfo.hEventTerminate = pThreadInfo->hEventTerminate;
+
+ // setup to wait
+ arHandles[0] = ThreadInfo.hEventTerminate;
+ arHandles[1] = ThreadInfo.hEventPowerEvent;
+
+ // do stuff ..
+ while (1)
+ {
+ // wait for an event to happen
+ dwWaitState = WaitForMultipleObjectsEx(2, arHandles, FALSE, INFINITE, FALSE);
+
+ switch (dwWaitState)
+ {
+ case WAIT_OBJECT_0:
+ // termination signaled
+ RevertToSelf();
CheckAndCloseHandle(ThreadInfo.hEventPowerEvent);
CheckAndCloseHandle(ThreadInfo.hEventResumeMain);
CheckAndCloseHandle(ThreadInfo.hEventTerminate);
- ExitThread(0);
- break;
-
- case WAIT_OBJECT_0+1:
- // Power event
- // - flush 'em!
- if (ImpersonateClient())
- {
- afsd_ServicePerformFlushVolumes();
- }
- // acknowledge event
- ResetEvent(ThreadInfo.hEventPowerEvent);
- break;
-
- case WAIT_ABANDONED_0:
- case WAIT_ABANDONED_0+1:
- case WAIT_IO_COMPLETION:
- case WAIT_TIMEOUT:
- // sno*
- LogEvent(EVENTLOG_WARNING_TYPE,
- MSG_FLUSH_UNEXPECTED_EVENT, NULL);
- break;
-
- } // end switch
-
- // signal back to waiting mainline
- SetEvent(ThreadInfo.hEventResumeMain);
-
- } // end while
-
- // I suppose we never get here
- ExitThread(0);
-}
+ ExitThread(0);
+ break;
+
+ case WAIT_OBJECT_0+1:
+ // Power event
+ // - flush 'em!
+ if (ImpersonateClient())
+ {
+ afsd_ServicePerformFlushVolumes();
+ }
+ // acknowledge event
+ ResetEvent(ThreadInfo.hEventPowerEvent);
+ break;
+
+ case WAIT_ABANDONED_0:
+ case WAIT_ABANDONED_0+1:
+ case WAIT_IO_COMPLETION:
+ case WAIT_TIMEOUT:
+ // sno*
+ LogEvent(EVENTLOG_WARNING_TYPE,
+ MSG_FLUSH_UNEXPECTED_EVENT, NULL);
+ break;
+
+ } // end switch
+
+ // signal back to waiting mainline
+ SetEvent(ThreadInfo.hEventResumeMain);
+
+ } // end while
+
+ // I suppose we never get here
+ ExitThread(0);
+}
/////////////////////////////////////////////////////////////////////
//
VOID
CheckAndCloseHandle(HANDLE thisHandle)
{
- if (thisHandle != NULL)
- {
- CloseHandle(thisHandle);
- thisHandle = NULL;
- }
+ if (thisHandle != NULL)
+ {
+ CloseHandle(thisHandle);
+ thisHandle = NULL;
+ }
}
//
BOOL
PowerNotificationThreadCreate()
{
- BOOL bSuccess = FALSE;
- DWORD dwThreadId = 0;
+ BOOL bSuccess = FALSE;
+ DWORD dwThreadId = 0;
char eventName[MAX_PATH];
- do
- {
- // create power event notification event
- // bManualReset=TRUE, bInitialState=FALSE
- gThreadInfo.hEventPowerEvent = CreateEvent(NULL, TRUE, FALSE,
+ do
+ {
+ // create power event notification event
+ // bManualReset=TRUE, bInitialState=FALSE
+ gThreadInfo.hEventPowerEvent = CreateEvent(NULL, TRUE, FALSE,
TEXT("afsd_flushvol_EventPowerEvent"));
if ( GetLastError() == ERROR_ALREADY_EXISTS )
afsi_log("Event Object Already Exists: %s", eventName);
- if (gThreadInfo.hEventPowerEvent == NULL)
- break;
+ if (gThreadInfo.hEventPowerEvent == NULL)
+ break;
- // create mainline resume event
- // bManualReset=FALSE, bInitialState=FALSE
- gThreadInfo.hEventResumeMain = CreateEvent(NULL, FALSE, FALSE,
+ // create mainline resume event
+ // bManualReset=FALSE, bInitialState=FALSE
+ gThreadInfo.hEventResumeMain = CreateEvent(NULL, FALSE, FALSE,
TEXT("afsd_flushvol_EventResumeMain"));
if ( GetLastError() == ERROR_ALREADY_EXISTS )
afsi_log("Event Object Already Exists: %s", eventName);
- if (gThreadInfo.hEventResumeMain == NULL)
- break;
+ if (gThreadInfo.hEventResumeMain == NULL)
+ break;
- // create thread terminate event
- // bManualReset=FALSE, bInitialState=FALSE
- gThreadInfo.hEventTerminate = CreateEvent(NULL, FALSE, FALSE,
+ // create thread terminate event
+ // bManualReset=FALSE, bInitialState=FALSE
+ gThreadInfo.hEventTerminate = CreateEvent(NULL, FALSE, FALSE,
TEXT("afsd_flushvol_EventTerminate"));
if ( GetLastError() == ERROR_ALREADY_EXISTS )
afsi_log("Event Object Already Exists: %s", eventName);
- if (gThreadInfo.hEventTerminate == NULL)
- break;
-
- // good so far - create thread
- gThreadHandle = CreateThread(NULL, 0,
- afsd_ServiceFlushVolumesThreadProc,
- (LPVOID) &gThreadInfo,
- 0, &dwThreadId);
+ if (gThreadInfo.hEventTerminate == NULL)
+ break;
+
+ // good so far - create thread
+ gThreadHandle = CreateThread(NULL, 0,
+ afsd_ServiceFlushVolumesThreadProc,
+ (LPVOID) &gThreadInfo,
+ 0, &dwThreadId);
- if (!gThreadHandle)
- break;
+ if (!gThreadHandle)
+ break;
- bSuccess = TRUE;
+ bSuccess = TRUE;
- } while (0);
+ } while (0);
- if (!bSuccess)
- {
- CheckAndCloseHandle(gThreadInfo.hEventPowerEvent);
- CheckAndCloseHandle(gThreadInfo.hEventResumeMain);
- CheckAndCloseHandle(gThreadInfo.hEventTerminate);
- CheckAndCloseHandle(gThreadHandle);
- }
+ if (!bSuccess)
+ {
+ CheckAndCloseHandle(gThreadInfo.hEventPowerEvent);
+ CheckAndCloseHandle(gThreadInfo.hEventResumeMain);
+ CheckAndCloseHandle(gThreadInfo.hEventTerminate);
+ CheckAndCloseHandle(gThreadHandle);
+ }
- return bSuccess;
+ return bSuccess;
}
//
BOOL
PowerNotificationThreadNotify()
{
- DWORD dwRet = 0;
- BOOL bRet = FALSE;
+ DWORD dwRet = 0;
+ BOOL bRet = FALSE;
- // Notify thread of power event, and wait for the HardDead timeout period
- dwRet = SignalObjectAndWait(
- gThreadInfo.hEventPowerEvent, // object to signal
- gThreadInfo.hEventResumeMain, // object to watch
- HardDeadtimeout*1000, // timeout (ms)
- FALSE // alertable
- );
+ // Notify thread of power event, and wait for the HardDead timeout period
+ dwRet = SignalObjectAndWait(
+ gThreadInfo.hEventPowerEvent, // object to signal
+ gThreadInfo.hEventResumeMain, // object to watch
+ HardDeadtimeout*1000, // timeout (ms)
+ FALSE // alertable
+ );
- if (dwRet == WAIT_OBJECT_0)
- bRet = TRUE;
+ if (dwRet == WAIT_OBJECT_0)
+ bRet = TRUE;
- return bRet;
+ return bRet;
}
//
VOID
PowerNotificationThreadExit()
{
- // ExitThread
- if (gThreadHandle)
- {
- SetEvent(gThreadInfo.hEventTerminate);
+ // ExitThread
+ if (gThreadHandle)
+ {
+ SetEvent(gThreadInfo.hEventTerminate);
WaitForSingleObject(gThreadHandle, INFINITE);
- CloseHandle(gThreadHandle);
- }
+ CloseHandle(gThreadHandle);
+ }
}
// The following is defined if you want to receive Power notifications,
// including Hibernation, and also subsequent flushing of AFS volumes
//
-#define REGISTER_POWER_NOTIFICATIONS
+#define REGISTER_POWER_NOTIFICATIONS 1
+#define FLUSH_VOLUME 1
//
// Check
*/
*/
static void afsd_notifier(char *msgp, char *filep, long line)
{
- char tbuffer[512];
- char *ptbuf[1];
- HANDLE h;
+ char tbuffer[512];
+ char *ptbuf[1];
+ HANDLE h;
- if (filep)
- sprintf(tbuffer, "Error at file %s, line %d: %s",
- filep, line, msgp);
- else
- sprintf(tbuffer, "Error at unknown location: %s", msgp);
+ if (filep)
+ sprintf(tbuffer, "Error at file %s, line %d: %s",
+ filep, line, msgp);
+ else
+ sprintf(tbuffer, "Error at unknown location: %s", msgp);
- h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
- ptbuf[0] = tbuffer;
- ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, line, NULL, 1, 0, ptbuf, NULL);
- DeregisterEventSource(h);
+ h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
+ ptbuf[0] = tbuffer;
+ ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, line, NULL, 1, 0, ptbuf, NULL);
+ DeregisterEventSource(h);
- GlobalStatus = line;
+ GlobalStatus = line;
- osi_LogEnable(afsd_logp);
+ osi_LogEnable(afsd_logp);
- afsd_ForceTrace(TRUE);
+ afsd_ForceTrace(TRUE);
afsi_log("--- begin dump ---");
cm_DumpSCache(afsi_file, "a");
DebugBreak();
- SetEvent(WaitToTerminate);
+ SetEvent(WaitToTerminate);
#ifdef JUMP
- if (GetCurrentThreadId() == MainThreadId)
- longjmp(notifier_jmp, 1);
- else
+ if (GetCurrentThreadId() == MainThreadId)
+ longjmp(notifier_jmp, 1);
+ else
#endif /* JUMP */
- ExitThread(1);
+ ExitThread(1);
}
/*
*/
static int _stdcall DummyMessageBox(HWND h, LPCTSTR l1, LPCTSTR l2, UINT ui)
{
- return 0;
+ return 0;
}
static SERVICE_STATUS ServiceStatus;
{
dwRet = NO_ERROR;
}
-
else
{
/* flush was unsuccessful, or timeout - deny shutdown */
VOID WINAPI
afsd_ServiceControlHandler(DWORD ctrlCode)
{
- HKEY parmKey;
- DWORD dummyLen, doTrace;
- long code;
-
- switch (ctrlCode) {
- case SERVICE_CONTROL_STOP:
- /* Shutdown RPC */
- RpcMgmtStopServerListening(NULL);
-
- /* Force trace if requested */
- code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- AFSConfigKeyName,
- 0, KEY_QUERY_VALUE, &parmKey);
- if (code != ERROR_SUCCESS)
- goto doneTrace;
-
- dummyLen = sizeof(doTrace);
- code = RegQueryValueEx(parmKey, "TraceOnShutdown",
- NULL, NULL,
- (BYTE *) &doTrace, &dummyLen);
- RegCloseKey (parmKey);
- if (code != ERROR_SUCCESS)
- doTrace = 0;
- if (doTrace)
- afsd_ForceTrace(FALSE);
-
-doneTrace:
- ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
- ServiceStatus.dwWin32ExitCode = NO_ERROR;
- ServiceStatus.dwCheckPoint = 1;
- ServiceStatus.dwWaitHint = 10000;
- ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
- SetServiceStatus(StatusHandle, &ServiceStatus);
- SetEvent(WaitToTerminate);
- break;
- case SERVICE_CONTROL_INTERROGATE:
- ServiceStatus.dwCurrentState = SERVICE_RUNNING;
- ServiceStatus.dwWin32ExitCode = NO_ERROR;
- ServiceStatus.dwCheckPoint = 0;
- ServiceStatus.dwWaitHint = 0;
- ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
- SetServiceStatus(StatusHandle, &ServiceStatus);
- break;
- /* XXX handle system shutdown */
- /* XXX handle pause & continue */
- }
-}
+ HKEY parmKey;
+ DWORD dummyLen, doTrace;
+ long code;
+
+ switch (ctrlCode) {
+ case SERVICE_CONTROL_STOP:
+ /* Shutdown RPC */
+ RpcMgmtStopServerListening(NULL);
+
+ /* Force trace if requested */
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ AFSConfigKeyName,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code != ERROR_SUCCESS)
+ goto doneTrace;
+
+ dummyLen = sizeof(doTrace);
+ code = RegQueryValueEx(parmKey, "TraceOnShutdown",
+ NULL, NULL,
+ (BYTE *) &doTrace, &dummyLen);
+ RegCloseKey (parmKey);
+ if (code != ERROR_SUCCESS)
+ doTrace = 0;
+ if (doTrace)
+ afsd_ForceTrace(FALSE);
+
+ doneTrace:
+ ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 1;
+ ServiceStatus.dwWaitHint = 10000;
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+ SetEvent(WaitToTerminate);
+ break;
+ case SERVICE_CONTROL_INTERROGATE:
+ ServiceStatus.dwCurrentState = SERVICE_RUNNING;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 0;
+ ServiceStatus.dwWaitHint = 0;
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+ break;
+ /* XXX handle system shutdown */
+ /* XXX handle pause & continue */
+ }
+}
/*
LPVOID lpContext
)
{
- HKEY parmKey;
- DWORD dummyLen, doTrace;
- long code;
+ HKEY parmKey;
+ DWORD dummyLen, doTrace;
+ long code;
DWORD dwRet = ERROR_CALL_NOT_IMPLEMENTED;
- switch (ctrlCode)
+ switch (ctrlCode)
{
case SERVICE_CONTROL_STOP:
/* Shutdown RPC */
dwRet = NO_ERROR;
break;
- /* XXX handle system shutdown */
- /* XXX handle pause & continue */
- case SERVICE_CONTROL_POWEREVENT:
- {
- /*
+ /* XXX handle system shutdown */
+ /* XXX handle pause & continue */
+ case SERVICE_CONTROL_POWEREVENT:
+ {
+ /*
** dwEventType of this notification == WPARAM of WM_POWERBROADCAST
- ** Return NO_ERROR == return TRUE for that message, i.e. accept request
- ** Return any error code to deny request,
- ** i.e. as if returning BROADCAST_QUERY_DENY
- */
- switch((int) dwEventType)
+ ** Return NO_ERROR == return TRUE for that message, i.e. accept request
+ ** Return any error code to deny request,
+ ** i.e. as if returning BROADCAST_QUERY_DENY
+ */
+ switch((int) dwEventType)
{
- case PBT_APMQUERYSUSPEND:
- case PBT_APMQUERYSTANDBY:
-
-#ifdef REGISTER_POWER_NOTIFICATIONS
- /* handle event */
- dwRet = afsd_ServiceFlushVolume((DWORD) lpEventData);
+ case PBT_APMQUERYSUSPEND:
+ case PBT_APMQUERYSTANDBY:
+
+#ifdef FLUSH_VOLUME
+ /* handle event */
+ dwRet = afsd_ServiceFlushVolume((DWORD) lpEventData);
#else
- dwRet = NO_ERROR;
+ dwRet = NO_ERROR;
#endif
- break;
+ break;
- /* allow remaining case PBT_WhatEver */
- case PBT_APMSUSPEND:
- case PBT_APMSTANDBY:
- case PBT_APMRESUMECRITICAL:
- case PBT_APMRESUMESUSPEND:
- case PBT_APMRESUMESTANDBY:
- case PBT_APMBATTERYLOW:
- case PBT_APMPOWERSTATUSCHANGE:
- case PBT_APMOEMEVENT:
- case PBT_APMRESUMEAUTOMATIC:
- default:
- dwRet = NO_ERROR;
- }
+ /* allow remaining case PBT_WhatEver */
+ case PBT_APMSUSPEND:
+ case PBT_APMSTANDBY:
+ case PBT_APMRESUMECRITICAL:
+ case PBT_APMRESUMESUSPEND:
+ case PBT_APMRESUMESTANDBY:
+ case PBT_APMBATTERYLOW:
+ case PBT_APMPOWERSTATUSCHANGE:
+ case PBT_APMOEMEVENT:
+ case PBT_APMRESUMEAUTOMATIC:
+ default:
+ dwRet = NO_ERROR;
+ }
}
} /* end switch(ctrlCode) */
- return dwRet;
+ return dwRet;
}
/* There is similar code in client_config\drivemap.cpp GlobalMountDrive()
sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSConfigKeyName);
- dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
- if (dwResult != ERROR_SUCCESS)
+ dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
+ if (dwResult != ERROR_SUCCESS)
return;
while (dwRetry < MAX_RETRIES) {
sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSConfigKeyName);
- dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
- if (dwResult != ERROR_SUCCESS)
+ dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
+ if (dwResult != ERROR_SUCCESS)
return;
while (1) {
void afsd_Main(DWORD argc, LPTSTR *argv)
{
- long code;
- char *reason;
+ long code;
+ char *reason;
#ifdef JUMP
- int jmpret;
+ int jmpret;
#endif /* JUMP */
HANDLE hInitHookDll;
HANDLE hAdvApi32;
#endif
osi_InitPanic(afsd_notifier);
- osi_InitTraceOption();
+ osi_InitTraceOption();
- GlobalStatus = 0;
+ GlobalStatus = 0;
- afsi_start();
+ afsi_start();
- WaitToTerminate = CreateEvent(NULL, TRUE, FALSE, TEXT("afsd_service_WaitToTerminate"));
+ WaitToTerminate = CreateEvent(NULL, TRUE, FALSE, TEXT("afsd_service_WaitToTerminate"));
if ( GetLastError() == ERROR_ALREADY_EXISTS )
afsi_log("Event Object Already Exists: %s", TEXT("afsd_service_WaitToTerminate"));
StatusHandle = RegisterServiceCtrlHandler(AFS_DAEMON_SERVICE_NAME, afsd_ServiceControlHandler);
}
- ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- ServiceStatus.dwServiceSpecificExitCode = 0;
- ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
- ServiceStatus.dwWin32ExitCode = NO_ERROR;
- ServiceStatus.dwCheckPoint = 1;
- ServiceStatus.dwWaitHint = 30000;
+ ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ ServiceStatus.dwServiceSpecificExitCode = 0;
+ ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 1;
+ ServiceStatus.dwWaitHint = 30000;
/* accept Power Events */
- ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_POWEREVENT;
- SetServiceStatus(StatusHandle, &ServiceStatus);
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_POWEREVENT;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
#endif
{
#ifdef JUMP
MainThreadId = GetCurrentThreadId();
- jmpret = setjmp(notifier_jmp);
+ jmpret = setjmp(notifier_jmp);
- if (jmpret == 0)
+ if (jmpret == 0)
#endif /* JUMP */
{
- code = afsd_InitCM(&reason);
- if (code != 0) {
+ code = afsd_InitCM(&reason);
+ if (code != 0) {
afsi_log("afsd_InitCM failed: %s (code = %d)", reason, code);
- osi_panic(reason, __FILE__, __LINE__);
+ osi_panic(reason, __FILE__, __LINE__);
}
#ifndef NOTSERVICE
ServiceStatus.dwWaitHint -= 5000;
SetServiceStatus(StatusHandle, &ServiceStatus);
#endif
- code = afsd_InitDaemons(&reason);
- if (code != 0) {
+ code = afsd_InitDaemons(&reason);
+ if (code != 0) {
afsi_log("afsd_InitDaemons failed: %s (code = %d)", reason, code);
osi_panic(reason, __FILE__, __LINE__);
}
ServiceStatus.dwWaitHint -= 5000;
SetServiceStatus(StatusHandle, &ServiceStatus);
#endif
- code = afsd_InitSMB(&reason, MessageBox);
- if (code != 0) {
+ code = afsd_InitSMB(&reason, MessageBox);
+ if (code != 0) {
afsi_log("afsd_InitSMB failed: %s (code = %d)", reason, code);
- osi_panic(reason, __FILE__, __LINE__);
+ osi_panic(reason, __FILE__, __LINE__);
}
MountGlobalDrives();
#ifndef NOTSERVICE
- ServiceStatus.dwCurrentState = SERVICE_RUNNING;
- ServiceStatus.dwWin32ExitCode = NO_ERROR;
- ServiceStatus.dwCheckPoint = 0;
- ServiceStatus.dwWaitHint = 0;
+ ServiceStatus.dwCurrentState = SERVICE_RUNNING;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 0;
+ ServiceStatus.dwWaitHint = 0;
/* accept Power events */
- ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_POWEREVENT;
- SetServiceStatus(StatusHandle, &ServiceStatus);
-#endif
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_POWEREVENT;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+#endif
{
HANDLE h; char *ptbuf[1];
- h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
- ptbuf[0] = "AFS running";
- ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
- DeregisterEventSource(h);
+ h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
+ ptbuf[0] = "AFS running";
+ ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
+ DeregisterEventSource(h);
}
- }
+ }
- WaitForSingleObject(WaitToTerminate, INFINITE);
+ WaitForSingleObject(WaitToTerminate, INFINITE);
{
- HANDLE h; char *ptbuf[1];
+ HANDLE h; char *ptbuf[1];
h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
ptbuf[0] = "AFS quitting";
ReportEvent(h, GlobalStatus ? EVENTLOG_ERROR_TYPE : EVENTLOG_INFORMATION_TYPE,
0, 0, NULL, 1, 0, ptbuf, NULL);
- DeregisterEventSource(h);
+ DeregisterEventSource(h);
}
DismountGlobalDrives();
rx_Finalize();
#ifdef REGISTER_POWER_NOTIFICATIONS
- /* terminate thread used to flush cache */
- PowerNotificationThreadExit();
+ /* terminate thread used to flush cache */
+ PowerNotificationThreadExit();
#endif
/* Remove the ExceptionFilter */
SetUnhandledExceptionFilter(NULL);
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
- ServiceStatus.dwWin32ExitCode = GlobalStatus ? ERROR_EXCEPTION_IN_SERVICE : NO_ERROR;
- ServiceStatus.dwCheckPoint = 0;
- ServiceStatus.dwWaitHint = 0;
- ServiceStatus.dwControlsAccepted = 0;
- SetServiceStatus(StatusHandle, &ServiceStatus);
-}
+ ServiceStatus.dwWin32ExitCode = GlobalStatus ? ERROR_EXCEPTION_IN_SERVICE : NO_ERROR;
+ ServiceStatus.dwCheckPoint = 0;
+ ServiceStatus.dwWaitHint = 0;
+ ServiceStatus.dwControlsAccepted = 0;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+}
DWORD __stdcall afsdMain_thread(void* notUsed)
{
int
main(void)
{
- static SERVICE_TABLE_ENTRY dispatchTable[] = {
- {AFS_DAEMON_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) afsd_Main},
- {NULL, NULL}
- };
+ static SERVICE_TABLE_ENTRY dispatchTable[] = {
+ {AFS_DAEMON_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) afsd_Main},
+ {NULL, NULL}
+ };
- if (!StartServiceCtrlDispatcher(dispatchTable))
+ if (!StartServiceCtrlDispatcher(dispatchTable))
{
LONG status = GetLastError();
- if (status == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
+ if (status == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
{
DWORD tid;
hAFSDMainThread = CreateThread(NULL, 0, afsdMain_thread, 0, 0, &tid);