#include <setjmp.h>
#include "afsd.h"
#include "afsd_init.h"
+#include "lanahelper.h"
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
HANDLE hAFSDWorkerThread[WORKER_THREADS];
#endif
-/* for the IFS version, set the event DoTerminate, on which all
- worker threads wait. they will exit, and then everything else
- can uninitialize. */
-HANDLE WaitToTerminate, DoTerminate;
+HANDLE WaitToTerminate;
-int GlobalStatus;
+static int GlobalStatus;
#ifdef JUMP
unsigned int MainThreadId;
extern int traceOnPanic;
extern HANDLE afsi_file;
-int powerEventsRegistered = 0;
+static int powerEventsRegistered = 0;
+extern int powerStateSuspended = 0;
/*
* Notifier function for use by osi_panic
*/
static void afsd_notifier(char *msgp, char *filep, long line)
{
- char tbuffer[512];
- char *ptbuf[1];
- HANDLE h;
+#ifdef AFSIFS
+ int i;
+#endif
if (filep)
- sprintf(tbuffer, "Error at file %s, line %d: %s",
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_SERVICE_ERROR_STOP_WITH_MSG_AND_LOCATION,
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);
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_SERVICE_ERROR_STOP_WITH_MSG, msgp);
GlobalStatus = line;
buf_ForceTrace(TRUE);
afsi_log("--- begin dump ---");
+ cm_DumpCells(afsi_file, "a", 0);
+ cm_DumpVolumes(afsi_file, "a", 0);
cm_DumpSCache(afsi_file, "a", 0);
#ifdef keisa
cm_dnlcDump(afsi_file, "a");
afsi_log("--- end dump ---");
#ifdef DEBUG
- DebugBreak();
+ if (IsDebuggerPresent())
+ DebugBreak();
#endif
-#ifndef AFSIFS
SetEvent(WaitToTerminate);
-#else
- SetEvent(DoTerminate);
+#ifdef AFSIFS
WaitForMultipleObjects(WORKER_THREADS, hAFSDWorkerThread, TRUE, INFINITE);
for (i = 0; i < WORKER_THREADS; i++)
CloseHandle(hAFSDWorkerThread[i]);
afsi_log("SERVICE_CONTROL_SHUTDOWN");
/* Write all dirty buffers back to server */
- buf_CleanAndReset();
+ if ( !lana_OnlyLoopback() )
+ buf_CleanAndReset();
/* Force trace if requested */
code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
}
doneTrace:
-#ifndef AFSIFS
SetEvent(WaitToTerminate);
-#else
- SetEvent(DoTerminate);
-#endif
break;
case SERVICE_CONTROL_INTERROGATE:
DWORD dummyLen, doTrace;
long code;
DWORD dwRet = ERROR_CALL_NOT_IMPLEMENTED;
+ OSVERSIONINFO osVersion;
+
+ /* Get the version of Windows */
+ memset(&osVersion, 0x00, sizeof(osVersion));
+ osVersion.dwOSVersionInfoSize = sizeof(osVersion);
+ GetVersionEx(&osVersion);
switch (ctrlCode)
{
SetServiceStatus(StatusHandle, &ServiceStatus);
/* Write all dirty buffers back to server */
- buf_CleanAndReset();
+ if ( !lana_OnlyLoopback() )
+ buf_CleanAndReset();
/* Force trace if requested */
code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
}
doneTrace:
-#ifndef AFSIFS
SetEvent(WaitToTerminate);
-#else
- SetEvent(DoTerminate);
-#endif
dwRet = NO_ERROR;
break;
/* XXX handle pause & continue */
case SERVICE_CONTROL_POWEREVENT:
{
- afsi_log("SERVICE_CONTROL_POWEREVENT");
+#ifdef DEBUG
+ afsi_log("SERVICE_CONTROL_POWEREVENT");
+#endif
/*
** dwEventType of this notification == WPARAM of WM_POWERBROADCAST
** Return NO_ERROR == return TRUE for that message, i.e. accept request
case PBT_APMQUERYSUSPEND:
afsi_log("SERVICE_CONTROL_APMQUERYSUSPEND");
/* Write all dirty buffers back to server */
- buf_CleanAndReset();
+ if ( !lana_OnlyLoopback() ) {
+ buf_CleanAndReset();
+ cm_SuspendSCache();
+ }
+ afsi_log("SERVICE_CONTROL_APMQUERYSUSPEND buf_CleanAndReset complete");
dwRet = NO_ERROR;
break;
case PBT_APMQUERYSTANDBY:
afsi_log("SERVICE_CONTROL_APMQUERYSTANDBY");
/* Write all dirty buffers back to server */
- buf_CleanAndReset();
+ if ( !lana_OnlyLoopback() ) {
+ buf_CleanAndReset();
+ cm_SuspendSCache();
+ }
+ afsi_log("SERVICE_CONTROL_APMQUERYSTANDBY buf_CleanAndReset complete");
dwRet = NO_ERROR;
break;
/* allow remaining case PBT_WhatEver */
case PBT_APMSUSPEND:
- afsi_log("SERVICE_CONTROL_APMSUSPEND");
+ afsi_log("SERVICE_CONTROL_APMSUSPEND");
+ powerStateSuspended = 1;
+ if (osVersion.dwMajorVersion >= 6) {
+ cm_SuspendSCache();
+ smb_StopListeners();
+ }
dwRet = NO_ERROR;
break;
case PBT_APMSTANDBY:
afsi_log("SERVICE_CONTROL_APMSTANDBY");
+ powerStateSuspended = 1;
+ if (osVersion.dwMajorVersion >= 6) {
+ cm_SuspendSCache();
+ smb_StopListeners();
+ }
dwRet = NO_ERROR;
break;
case PBT_APMRESUMECRITICAL:
afsi_log("SERVICE_CONTROL_APMRESUMECRITICAL");
+ if (osVersion.dwMajorVersion >= 6)
+ smb_RestartListeners();
dwRet = NO_ERROR;
break;
case PBT_APMRESUMESUSPEND:
+ /* User logged in after suspend */
afsi_log("SERVICE_CONTROL_APMRESUMESUSPEND");
dwRet = NO_ERROR;
break;
- case PBT_APMRESUMESTANDBY:
+ case PBT_APMRESUMESTANDBY:
+ /* User logged in after standby */
afsi_log("SERVICE_CONTROL_APMRESUMESTANDBY");
dwRet = NO_ERROR;
break;
dwRet = NO_ERROR;
break;
case PBT_APMPOWERSTATUSCHANGE:
- afsi_log("SERVICE_CONTROL_APMPOWERSTATUSCHANGE");
+#ifdef DEBUG
+ afsi_log("SERVICE_CONTROL_APMPOWERSTATUSCHANGE");
+#endif
dwRet = NO_ERROR;
break;
case PBT_APMOEMEVENT:
+#ifdef DEBUG
afsi_log("SERVICE_CONTROL_APMOEMEVENT");
+#endif
dwRet = NO_ERROR;
break;
- case PBT_APMRESUMEAUTOMATIC:
+ case PBT_APMRESUMEAUTOMATIC:
+ /* This is the message delivered once all devices are up */
afsi_log("SERVICE_CONTROL_APMRESUMEAUTOMATIC");
+ powerStateSuspended = 0;
+ if (osVersion.dwMajorVersion >= 6)
+ smb_RestartListeners();
dwRet = NO_ERROR;
break;
default:
{
afsi_log("SERVICE_CONTROL_CUSTOM_DUMP");
GenerateMiniDump(NULL);
- dwRet = NO_ERROR;
+ dwRet = NO_ERROR;
}
break;
} /* end switch(ctrlCode) */
* Mount a drive into AFS if there global mapping
*/
/* DEE Could check first if we are run as SYSTEM */
-#define MAX_RETRIES 30
-static void MountGlobalDrives(void)
+#define MAX_RETRIES 10
+#define MAX_DRIVES 23
+static DWORD __stdcall MountGlobalDrivesThread(void * notUsed)
{
+#ifndef AFSIFS
char szAfsPath[_MAX_PATH];
+#endif
char szDriveToMapTo[5];
DWORD dwResult;
char szKeyName[256];
if (dwResult != ERROR_SUCCESS)
return;
- while (dwRetry < MAX_RETRIES) {
+ while (dwIndex < MAX_DRIVES) {
dwDriveSize = sizeof(szDriveToMapTo);
dwSubMountSize = sizeof(szSubMount);
dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize, 0, &dwType, szSubMount, &dwSubMountSize);
}
#ifndef AFSIFS
- for ( ; dwRetry < MAX_RETRIES; dwRetry++)
+ for (dwRetry = 0 ; dwRetry < MAX_RETRIES; dwRetry++)
{
NETRESOURCE nr;
memset (&nr, 0x00, sizeof(NETRESOURCE));
}
#else
/* FIXFIX: implement */
+ afsi_log("GlobalAutoMap of %s to %s not implemented", szDriveToMapTo, szSubMount);
#endif
}
RegCloseKey(hKey);
+ return 0;
+}
+
+static HANDLE hThreadMountGlobalDrives = NULL;
+
+static void MountGlobalDrives()
+{
+ DWORD tid;
+
+ hThreadMountGlobalDrives = CreateThread(NULL, 0, MountGlobalDrivesThread, 0, 0, &tid);
+
+ if ( hThreadMountGlobalDrives ) {
+ DWORD rc = WaitForSingleObject( hThreadMountGlobalDrives, 15000 );
+ if (rc == WAIT_TIMEOUT) {
+ afsi_log("GlobalAutoMap thread failed to complete after 15 seconds");
+ } else if (rc == WAIT_OBJECT_0) {
+ afsi_log("GlobalAutoMap thread completed");
+ CloseHandle( hThreadMountGlobalDrives );
+ hThreadMountGlobalDrives = NULL;
+ }
+ }
}
static void DismountGlobalDrives()
{
+#ifndef AFSIFS
char szAfsPath[_MAX_PATH];
char szDriveToMapTo[5];
- DWORD dwResult;
- char szKeyName[256];
- HKEY hKey;
- DWORD dwIndex = 0;
DWORD dwDriveSize;
DWORD dwSubMountSize;
char szSubMount[256];
DWORD dwType;
+#endif
+ DWORD dwResult;
+ char szKeyName[256];
+ HKEY hKey;
+ DWORD dwIndex = 0;
+
+ if ( hThreadMountGlobalDrives ) {
+ DWORD rc = WaitForSingleObject(hThreadMountGlobalDrives, 0);
+
+ if (rc == WAIT_TIMEOUT) {
+ afsi_log("GlobalAutoMap thread failed to complete before service shutdown");
+ }
+ else if (rc == WAIT_OBJECT_0) {
+ afsi_log("GlobalAutoMap thread completed");
+ CloseHandle( hThreadMountGlobalDrives );
+ hThreadMountGlobalDrives = NULL;
+ }
+ }
sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSREG_CLT_SVC_PARAM_SUBKEY);
if (dwResult != ERROR_SUCCESS)
return;
-#ifndef AFSIFS
- while (1) {
+#ifdef AFSIFS
+ /* FIXFIX: implement */
+#else
+ while (dwIndex < MAX_DRIVES) {
dwDriveSize = sizeof(szDriveToMapTo);
dwSubMountSize = sizeof(szSubMount);
dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize, 0, &dwType, szSubMount, &dwSubMountSize);
afsi_log("Disconnect from GlobalAutoMap of %s to %s %s", szDriveToMapTo, szSubMount, dwResult ? "succeeded" : "failed");
}
-#else
- /* FIXFIX: implement */
#endif
RegCloseKey(hKey);
#endif /* JUMP */
HMODULE hHookDll;
HMODULE hAdvApi32;
+#ifdef AFSIFS
+ int cnt;
+#endif
#ifdef _DEBUG
+ afsd_DbgBreakAllocInit();
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF /*| _CRTDBG_CHECK_ALWAYS_DF*/ |
_CRTDBG_CHECK_CRT_DF /* | _CRTDBG_DELAY_FREE_MEM_DF */ );
#endif
+ afsd_SetUnhandledExceptionFilter();
+
osi_InitPanic(afsd_notifier);
osi_InitTraceOption();
if ( GetLastError() == ERROR_ALREADY_EXISTS )
afsi_log("Event Object Already Exists: %s", TEXT("afsd_service_WaitToTerminate"));
-#ifdef AFSIFS
- DoTerminate = CreateEvent(NULL, TRUE, FALSE, TEXT("afsd_service_DoTerminate"));
- if ( GetLastError() == ERROR_ALREADY_EXISTS )
- afsi_log("Event Object Already Exists: %s", TEXT("afsd_service_DoTerminate"));
-#endif
-
#ifndef NOTSERVICE
hAdvApi32 = LoadLibrary("advapi32.dll");
if (hAdvApi32 == NULL)
SetServiceStatus(StatusHandle, &ServiceStatus);
#endif
- {
- HANDLE h; char *ptbuf[1];
- h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
- ptbuf[0] = "AFS start pending";
- ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
- DeregisterEventSource(h);
- }
+ LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_SERVICE_START_PENDING);
#ifdef REGISTER_POWER_NOTIFICATIONS
{
ServiceStatus.dwControlsAccepted = 0;
SetServiceStatus(StatusHandle, &ServiceStatus);
- {
- HANDLE h; char *ptbuf[1];
- h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
- ptbuf[0] = "Incorrect module versions loaded";
- ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
- DeregisterEventSource(h);
- }
-
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_SERVICE_INCORRECT_VERSIONS);
+
/* exit if initialization failed */
return;
}
}
}
+ /* Perform Volume Status Notification Initialization */
+ cm_VolStatus_Initialization();
+
#ifdef JUMP
MainThreadId = GetCurrentThreadId();
jmpret = setjmp(notifier_jmp);
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_PARAMCHANGE;
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);
- }
+
+ LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_SERVICE_RUNNING);
}
+ /* Notify any volume status handlers that we have started */
+ cm_VolStatus_Service_Started();
+
/* allow an exit to be called when started */
hHookDll = LoadLibrary(AFSD_HOOK_DLL);
if (hHookDll)
afsi_log("Received Termination Signal, Stopping Service");
- {
- 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);
- }
+ if ( GlobalStatus )
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_SERVICE_ERROR_STOP);
+ else
+ LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_SERVICE_STOPPING);
+
+ /* Notify any Volume Status Handlers that we are stopping */
+ cm_VolStatus_Service_Stopped();
/* allow an exit to be called prior to stopping the service */
hHookDll = LoadLibrary(AFSD_HOOK_DLL);
cm_DaemonShutdown();
afsi_log("Daemon shutdown complete");
-
+
+ afsd_ShutdownCM();
+
buf_Shutdown();
afsi_log("Buffer shutdown complete");
afsi_log("rx finalization complete");
#ifndef AFSIFS
- smb_Shutdown();
+ smb_Shutdown();
afsi_log("smb shutdown complete");
#endif
PowerNotificationThreadExit();
#endif
+ /* Cleanup any Volume Status Notification Handler */
+ cm_VolStatus_Finalize();
+
/* allow an exit to be called after stopping the service */
hHookDll = LoadLibrary(AFSD_HOOK_DLL);
if (hHookDll)
printf("Hit <Enter> to terminate OpenAFS Client Service\n");
getchar();
-#ifndef AFSIFS
SetEvent(WaitToTerminate);
-#else
- SetEvent(DoTerminate);
- dc_release_hooks();
+#ifdef AFSIFS
+ dc_release_hooks();
#endif
}
}