diff --git a/src/WINNT/afsd/afsd_flushvol.c b/src/WINNT/afsd/afsd_flushvol.c index 32ab70025a..5d90c7fbac 100644 --- a/src/WINNT/afsd/afsd_flushvol.c +++ b/src/WINNT/afsd/afsd_flushvol.c @@ -27,6 +27,9 @@ #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; @@ -45,145 +48,150 @@ 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; +{ + 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 \\-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(); - // Determine the root share name (\\AFS\ALL or \\-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; - } + // display total volume count in Event Logger + sprintf(bufMessage, "%d", dwTotalVols); + LogTimingEvent(MSG_TIME_FLUSH_TOTAL, bufMessage, + dwFlushEnd - dwFlushBegin); - // 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(); - - // 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. @@ -193,11 +201,11 @@ afsd_ServicePerformFlushVolumes() 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); } @@ -223,91 +231,91 @@ LogTimingEvent(DWORD dwEventID, LPTSTR lpString1, DWORD dwTime) // HANDLE GetUserToken(DWORD access) { - HANDLE hTok = NULL; - DWORD pid = 0, tid = 0; + 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); - } + // 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; + // 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); - } + // 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); - } + // 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); - } + // 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); - } - } + // + // 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; -} + // 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; } ///////////////////////////////////////////////////////////////////// @@ -317,67 +325,67 @@ ImpersonateClient() DWORD WINAPI afsd_ServiceFlushVolumesThreadProc(LPVOID lpParam) { - FLUSHVOLTHREADINFO ThreadInfo; - PFLUSHVOLTHREADINFO pThreadInfo = (PFLUSHVOLTHREADINFO) lpParam; - HANDLE arHandles[2] = {0}; - DWORD dwWaitState = 0; + 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; + // 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; + // 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); + // 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(); + switch (dwWaitState) + { + case WAIT_OBJECT_0: + // termination signaled + RevertToSelf(); CheckAndCloseHandle(ThreadInfo.hEventPowerEvent); CheckAndCloseHandle(ThreadInfo.hEventResumeMain); CheckAndCloseHandle(ThreadInfo.hEventTerminate); - ExitThread(0); - break; + ExitThread(0); + break; - case WAIT_OBJECT_0+1: - // Power event - // - flush 'em! - if (ImpersonateClient()) - { - afsd_ServicePerformFlushVolumes(); - } - // acknowledge event - ResetEvent(ThreadInfo.hEventPowerEvent); - 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 + 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; - // signal back to waiting mainline - SetEvent(ThreadInfo.hEventResumeMain); + } // end switch - } // end while - - // I suppose we never get here - ExitThread(0); -} + // signal back to waiting mainline + SetEvent(ThreadInfo.hEventResumeMain); + + } // end while + + // I suppose we never get here + ExitThread(0); +} ///////////////////////////////////////////////////////////////////// // @@ -387,11 +395,11 @@ afsd_ServiceFlushVolumesThreadProc(LPVOID lpParam) VOID CheckAndCloseHandle(HANDLE thisHandle) { - if (thisHandle != NULL) - { - CloseHandle(thisHandle); - thisHandle = NULL; - } + if (thisHandle != NULL) + { + CloseHandle(thisHandle); + thisHandle = NULL; + } } // @@ -400,62 +408,62 @@ CheckAndCloseHandle(HANDLE thisHandle) 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; + if (gThreadInfo.hEventTerminate == NULL) + break; - // good so far - create thread - gThreadHandle = CreateThread(NULL, 0, - afsd_ServiceFlushVolumesThreadProc, - (LPVOID) &gThreadInfo, - 0, &dwThreadId); + // 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; } // @@ -464,21 +472,21 @@ PowerNotificationThreadCreate() 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; } // @@ -487,12 +495,12 @@ PowerNotificationThreadNotify() VOID PowerNotificationThreadExit() { - // ExitThread - if (gThreadHandle) - { - SetEvent(gThreadInfo.hEventTerminate); + // ExitThread + if (gThreadHandle) + { + SetEvent(gThreadInfo.hEventTerminate); WaitForSingleObject(gThreadHandle, INFINITE); - CloseHandle(gThreadHandle); - } + CloseHandle(gThreadHandle); + } } diff --git a/src/WINNT/afsd/afsd_service.c b/src/WINNT/afsd/afsd_service.c index 0517edec79..c69da6593f 100644 --- a/src/WINNT/afsd/afsd_service.c +++ b/src/WINNT/afsd/afsd_service.c @@ -32,7 +32,8 @@ // 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 */ @@ -59,26 +60,26 @@ extern HANDLE afsi_file; */ 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"); @@ -91,14 +92,14 @@ static void afsd_notifier(char *msgp, char *filep, long line) 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); } /* @@ -106,7 +107,7 @@ static void afsd_notifier(char *msgp, char *filep, long line) */ static int _stdcall DummyMessageBox(HWND h, LPCTSTR l1, LPCTSTR l2, UINT ui) { - return 0; + return 0; } static SERVICE_STATUS ServiceStatus; @@ -130,7 +131,6 @@ afsd_ServiceFlushVolume(DWORD dwlpEventData) { dwRet = NO_ERROR; } - else { /* flush was unsuccessful, or timeout - deny shutdown */ @@ -151,53 +151,53 @@ afsd_ServiceFlushVolume(DWORD dwlpEventData) VOID WINAPI afsd_ServiceControlHandler(DWORD ctrlCode) { - HKEY parmKey; - DWORD dummyLen, doTrace; - long code; + HKEY parmKey; + DWORD dummyLen, doTrace; + long code; - switch (ctrlCode) { - case SERVICE_CONTROL_STOP: - /* Shutdown RPC */ - RpcMgmtStopServerListening(NULL); + 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; + /* 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); + 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 */ - } -} + 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 */ + } +} /* @@ -212,12 +212,12 @@ afsd_ServiceControlHandlerEx( 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 */ @@ -261,45 +261,45 @@ afsd_ServiceControlHandlerEx( 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() @@ -323,8 +323,8 @@ static void MountGlobalDrives() 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) { @@ -385,8 +385,8 @@ static void DismountGlobalDrives() 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) { @@ -428,10 +428,10 @@ RegisterServiceCtrlHandlerFunc pRegisterServiceCtrlHandler = NULL; 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; @@ -443,13 +443,13 @@ void afsd_Main(DWORD argc, LPTSTR *argv) #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")); @@ -472,15 +472,15 @@ void afsd_Main(DWORD argc, LPTSTR *argv) 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 { @@ -538,15 +538,15 @@ void afsd_Main(DWORD argc, LPTSTR *argv) #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 @@ -554,8 +554,8 @@ void afsd_Main(DWORD argc, LPTSTR *argv) 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__); } @@ -565,42 +565,42 @@ void afsd_Main(DWORD argc, LPTSTR *argv) 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(); @@ -608,20 +608,20 @@ void afsd_Main(DWORD argc, LPTSTR *argv) 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) { @@ -633,15 +633,15 @@ 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); diff --git a/src/WINNT/afsd/lanahelper.cpp b/src/WINNT/afsd/lanahelper.cpp index d704adac67..5cdc27bd5e 100644 --- a/src/WINNT/afsd/lanahelper.cpp +++ b/src/WINNT/afsd/lanahelper.cpp @@ -394,6 +394,35 @@ extern "C" lana_number_t lana_FindLoopback(void) return LANA_INVALID; } +/* Returns TRUE if all adapters are loopback adapters */ +extern "C" BOOL lana_OnlyLoopback(void) +{ + NCB ncb; + LANA_ENUM lana_list; + int status; + int i; + + memset(&ncb, 0, sizeof(ncb)); + ncb.ncb_command = NCBENUM; + ncb.ncb_buffer = (UCHAR *) &lana_list; + ncb.ncb_length = sizeof(lana_list); + status = Netbios(&ncb); + if (status != 0) { +#ifndef NOLOGGING + afsi_log("Netbios NCBENUM failed: status %ld", status); +#endif + return FALSE; + } + for (i = 0; i < lana_list.length; i++) { + if (!lana_IsLoopback(lana_list.lana[i])) { + // Found one non-Loopback adapter + return FALSE; + } + } + // All adapters are loopback + return TRUE; +} + // Is the given lana a Windows Loopback Adapter? // TODO: implement a better check for loopback // TODO: also check for proper bindings (IPv4) diff --git a/src/WINNT/afsd/lanahelper.h b/src/WINNT/afsd/lanahelper.h index d6ba0ed85f..22e88e311b 100644 --- a/src/WINNT/afsd/lanahelper.h +++ b/src/WINNT/afsd/lanahelper.h @@ -59,6 +59,8 @@ extern "C" { lana_number_t lana_FindLoopback(void); + BOOL lana_OnlyLoopback(void); + BOOL lana_IsLoopback(lana_number_t lana); long lana_GetUncServerNameEx(char *buffer, lana_number_t * pLana, int * pIsGateway, int flags);