-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-#include <afs/param.h>
#include <afs/stds.h>
#include <windows.h>
#include <setjmp.h>
#include "afsd.h"
#include "afsd_init.h"
+#include "lanahelper.h"
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
+#include <WINNT\afsreg.h>
#include <osi.h>
#ifdef _DEBUG
#include <crtdbg.h>
#endif
+#include "afsdifs.h"
-/*
-// The following is defined if you want to receive Power notifications,
-// including Hibernation, and also subsequent flushing of AFS volumes
-//
-#define REGISTER_POWER_NOTIFICATIONS 1
-#define FLUSH_VOLUME 1
-//
-// Check
-*/
+//#define REGISTER_POWER_NOTIFICATIONS 1
#include "afsd_flushvol.h"
extern void afsi_log(char *pattern, ...);
+static SERVICE_STATUS ServiceStatus;
+static SERVICE_STATUS_HANDLE StatusHandle;
+
HANDLE hAFSDMainThread = NULL;
+#ifdef AFSIFS
+HANDLE hAFSDWorkerThread[WORKER_THREADS];
+#endif
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_DumpSCache(afsi_file, "a");
+ 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");
#endif
- cm_DumpBufHashTable(afsi_file, "a");
- smb_DumpVCP(afsi_file, "a");
+ cm_DumpBufHashTable(afsi_file, "a", 0);
+ smb_DumpVCP(afsi_file, "a", 0);
afsi_log("--- end dump ---");
#ifdef DEBUG
- DebugBreak();
+ if (IsDebuggerPresent())
+ DebugBreak();
#endif
SetEvent(WaitToTerminate);
+#ifdef AFSIFS
+ WaitForMultipleObjects(WORKER_THREADS, hAFSDWorkerThread, TRUE, INFINITE);
+ for (i = 0; i < WORKER_THREADS; i++)
+ CloseHandle(hAFSDWorkerThread[i]);
+#endif
#ifdef JUMP
if (GetCurrentThreadId() == MainThreadId)
longjmp(notifier_jmp, 1);
- else
#endif /* JUMP */
- ExitThread(1);
+
+ ServiceStatus.dwCurrentState = SERVICE_STOPPED;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 0;
+ ServiceStatus.dwWaitHint = 0;
+ ServiceStatus.dwControlsAccepted = 0;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+
+ exit(1);
}
/*
return 0;
}
-static SERVICE_STATUS ServiceStatus;
-static SERVICE_STATUS_HANDLE StatusHandle;
-
DWORD
afsd_ServiceFlushVolume(DWORD dwlpEventData)
{
long code;
switch (ctrlCode) {
+ case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
- /* Shutdown RPC */
- RpcMgmtStopServerListening(NULL);
+ ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 1;
+ ServiceStatus.dwWaitHint = 30000;
+ ServiceStatus.dwControlsAccepted = 0;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+
+ if (ctrlCode == SERVICE_CONTROL_STOP)
+ afsi_log("SERVICE_CONTROL_STOP");
+ else
+ afsi_log("SERVICE_CONTROL_SHUTDOWN");
+
+ /* Write all dirty buffers back to server */
+ if ( !lana_OnlyLoopback() )
+ buf_CleanAndReset();
/* Force trace if requested */
code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- AFSConfigKeyName,
+ AFSREG_CLT_SVC_PARAM_SUBKEY,
0, KEY_QUERY_VALUE, &parmKey);
if (code != ERROR_SUCCESS)
goto doneTrace;
}
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;
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
SetServiceStatus(StatusHandle, &ServiceStatus);
break;
/* XXX handle system shutdown */
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)
{
+ case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
- /* Shutdown RPC */
- RpcMgmtStopServerListening(NULL);
+ ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 1;
+ ServiceStatus.dwWaitHint = 30000;
+ ServiceStatus.dwControlsAccepted = 0;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+
+ /* Write all dirty buffers back to server */
+ if ( !lana_OnlyLoopback() )
+ buf_CleanAndReset();
/* Force trace if requested */
code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- AFSConfigKeyName,
+ AFSREG_CLT_SVC_PARAM_SUBKEY,
0, KEY_QUERY_VALUE, &parmKey);
if (code != ERROR_SUCCESS)
goto doneTrace;
}
doneTrace:
- ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
- ServiceStatus.dwWin32ExitCode = NO_ERROR;
- ServiceStatus.dwCheckPoint = 1;
- ServiceStatus.dwWaitHint = 10000;
- ServiceStatus.dwControlsAccepted = 0;
- SetServiceStatus(StatusHandle, &ServiceStatus);
SetEvent(WaitToTerminate);
dwRet = NO_ERROR;
break;
ServiceStatus.dwWin32ExitCode = NO_ERROR;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
- ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_POWEREVENT;
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT;
SetServiceStatus(StatusHandle, &ServiceStatus);
+ afsi_log("SERVICE_CONTROL_INTERROGATE");
dwRet = NO_ERROR;
break;
/* XXX handle system shutdown */
/* XXX handle pause & continue */
case 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
if (powerEventsRegistered) {
switch((int) dwEventType)
{
- case PBT_APMQUERYSUSPEND:
+ case PBT_APMQUERYSUSPEND:
+ afsi_log("SERVICE_CONTROL_APMQUERYSUSPEND");
+ /* Write all dirty buffers back to server */
+ if ( !lana_OnlyLoopback() ) {
+ buf_CleanAndReset();
+ cm_SuspendSCache();
+ }
+ afsi_log("SERVICE_CONTROL_APMQUERYSUSPEND buf_CleanAndReset complete");
+ dwRet = NO_ERROR;
+ break;
case PBT_APMQUERYSTANDBY:
-
-#ifdef FLUSH_VOLUME
- /* handle event */
- dwRet = afsd_ServiceFlushVolume((DWORD) lpEventData);
-#else
+ afsi_log("SERVICE_CONTROL_APMQUERYSTANDBY");
+ /* Write all dirty buffers back to server */
+ if ( !lana_OnlyLoopback() ) {
+ buf_CleanAndReset();
+ cm_SuspendSCache();
+ }
+ afsi_log("SERVICE_CONTROL_APMQUERYSTANDBY buf_CleanAndReset complete");
dwRet = NO_ERROR;
-#endif
break;
/* allow remaining case PBT_WhatEver */
- case PBT_APMSUSPEND:
- case PBT_APMSTANDBY:
- case PBT_APMRESUMECRITICAL:
+ case PBT_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:
- case PBT_APMRESUMESTANDBY:
+ /* User logged in after suspend */
+ afsi_log("SERVICE_CONTROL_APMRESUMESUSPEND");
+ dwRet = NO_ERROR;
+ break;
+ case PBT_APMRESUMESTANDBY:
+ /* User logged in after standby */
+ afsi_log("SERVICE_CONTROL_APMRESUMESTANDBY");
+ dwRet = NO_ERROR;
+ break;
case PBT_APMBATTERYLOW:
+ afsi_log("SERVICE_CONTROL_APMBATTERYLOW");
+ dwRet = NO_ERROR;
+ break;
case PBT_APMPOWERSTATUSCHANGE:
+#ifdef DEBUG
+ afsi_log("SERVICE_CONTROL_APMPOWERSTATUSCHANGE");
+#endif
+ dwRet = NO_ERROR;
+ break;
case PBT_APMOEMEVENT:
- case PBT_APMRESUMEAUTOMATIC:
+#ifdef DEBUG
+ afsi_log("SERVICE_CONTROL_APMOEMEVENT");
+#endif
+ dwRet = NO_ERROR;
+ break;
+ 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:
- dwRet = NO_ERROR;
+ afsi_log("SERVICE_CONTROL_unknown");
+ dwRet = NO_ERROR;
}
}
}
+ break;
+ case SERVICE_CONTROL_CUSTOM_DUMP:
+ {
+ afsi_log("SERVICE_CONTROL_CUSTOM_DUMP");
+ GenerateMiniDump(NULL);
+ dwRet = NO_ERROR;
+ }
+ break;
} /* end switch(ctrlCode) */
return dwRet;
}
* 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];
char szSubMount[256];
DWORD dwType;
- sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSConfigKeyName);
+ sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSREG_CLT_SVC_PARAM_SUBKEY);
dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
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);
}
}
- for ( ; dwRetry < MAX_RETRIES; dwRetry++)
- {
- NETRESOURCE nr;
- memset (&nr, 0x00, sizeof(NETRESOURCE));
-
- sprintf(szAfsPath,"\\\\%s\\%s",cm_NetbiosName,szSubMount);
-
- nr.dwScope = RESOURCE_GLOBALNET; /* ignored parameter */
- nr.dwType=RESOURCETYPE_DISK;
- nr.lpLocalName=szDriveToMapTo;
- nr.lpRemoteName=szAfsPath;
- nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE; /* ignored parameter */
- nr.dwUsage = RESOURCEUSAGE_CONNECTABLE; /* ignored parameter */
-
- dwResult = WNetAddConnection2(&nr,NULL,NULL,0);
+#ifndef AFSIFS
+ for (dwRetry = 0 ; dwRetry < MAX_RETRIES; dwRetry++)
+ {
+ NETRESOURCE nr;
+ memset (&nr, 0x00, sizeof(NETRESOURCE));
+
+ sprintf(szAfsPath,"\\\\%s\\%s",cm_NetbiosName,szSubMount);
+
+ nr.dwScope = RESOURCE_GLOBALNET; /* ignored parameter */
+ nr.dwType=RESOURCETYPE_DISK;
+ nr.lpLocalName=szDriveToMapTo;
+ nr.lpRemoteName=szAfsPath;
+ nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE; /* ignored parameter */
+ nr.dwUsage = RESOURCEUSAGE_CONNECTABLE; /* ignored parameter */
+
+ dwResult = WNetAddConnection2(&nr,NULL,NULL,0);
afsi_log("GlobalAutoMap of %s to %s %s (%d)", szDriveToMapTo, szSubMount,
(dwResult == NO_ERROR) ? "succeeded" : "failed", dwResult);
if (dwResult == NO_ERROR) {
/* Disconnect any previous mappings */
dwResult = WNetCancelConnection2(szDriveToMapTo, 0, TRUE);
}
+#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", AFSConfigKeyName);
+ sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSREG_CLT_SVC_PARAM_SUBKEY);
dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
if (dwResult != ERROR_SUCCESS)
return;
- 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");
}
+#endif
RegCloseKey(hKey);
}
return retval;
}
+static HINSTANCE hCrypt32;
+static DWORD (WINAPI *pCertGetNameString)(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags,
+ void* pvTypePara, LPTSTR pszNameString, DWORD cchNameString);
+static BOOL (WINAPI *pCryptQueryObject)(DWORD dwObjectType, const void* pvObject, DWORD dwExpectedContentTypeFlags,
+ DWORD dwExpectedFormatTypeFlags, DWORD dwFlags,
+ DWORD* pdwMsgAndCertEncodingType, DWORD* pdwContentType,
+ DWORD* pdwFormatType, HCERTSTORE* phCertStore,
+ HCRYPTMSG* phMsg, const void** ppvContext);
+static BOOL (WINAPI *pCryptMsgGetParam)(HCRYPTMSG hCryptMsg, DWORD dwParamType, DWORD dwIndex,
+ void* pvData, DWORD* pcbData);
+static PCCERT_CONTEXT (WINAPI *pCertFindCertificateInStore)(HCERTSTORE hCertStore, DWORD dwCertEncodingType,
+ DWORD dwFindFlags, DWORD dwFindType,
+ const void* pvFindPara,
+ PCCERT_CONTEXT pPrevCertContext);
+static BOOL (WINAPI *pCertCloseStore)(HCERTSTORE hCertStore, DWORD dwFlags);
+static BOOL (WINAPI *pCryptMsgClose)(HCRYPTMSG hCryptMsg);
+static BOOL (WINAPI *pCertCompareCertificate)(DWORD dwCertEncodingType, PCERT_INFO pCertId1,
+ PCERT_INFO pCertId2);
+static BOOL (WINAPI *pCertFreeCertificateContext)(PCCERT_CONTEXT pCertContext);
+
+void LoadCrypt32(void)
+{
+ hCrypt32 = LoadLibrary("crypt32");
+ if ( !hCrypt32 )
+ return;
+
+ (FARPROC) pCertGetNameString = GetProcAddress( hCrypt32, "CertGetNameString" );
+ (FARPROC) pCryptQueryObject = GetProcAddress( hCrypt32, "CryptQueryObject" );
+ (FARPROC) pCryptMsgGetParam = GetProcAddress( hCrypt32, "CryptMsgGetParam" );
+ (FARPROC) pCertFindCertificateInStore = GetProcAddress( hCrypt32, "CertFindCertificateInStore" );
+ (FARPROC) pCertCloseStore = GetProcAddress( hCrypt32, "CertCloseStore" );
+ (FARPROC) pCryptMsgClose = GetProcAddress( hCrypt32, "CryptMsgClose" );
+ (FARPROC) pCertCompareCertificate = GetProcAddress( hCrypt32, "CertCompareCertificate" );
+ (FARPROC) pCertFreeCertificateContext = GetProcAddress( hCrypt32, "CertFreeCertificateContext" );
+
+ if ( !pCertGetNameString ||
+ !pCryptQueryObject ||
+ !pCryptMsgGetParam ||
+ !pCertFindCertificateInStore ||
+ !pCertCloseStore ||
+ !pCryptMsgClose ||
+ !pCertCompareCertificate ||
+ !pCertFreeCertificateContext)
+ {
+ FreeLibrary(hCrypt32);
+ hCrypt32 = NULL;
+ }
+}
+
+void UnloadCrypt32(void)
+{
+ FreeLibrary(hCrypt32);
+}
+
#define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
PCCERT_CONTEXT GetCertCtx(CHAR * filename)
PCCERT_CONTEXT pCertContext = NULL;
CERT_INFO CertInfo;
+ if ( hCrypt32 == NULL )
+ return NULL;
+
ZeroMemory(&CertInfo, sizeof(CertInfo));
mbstowcs(wfilename, filename, 260);
- fResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
- wfilename,
- CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
- CERT_QUERY_FORMAT_FLAG_BINARY,
- 0,
- &dwEncoding,
- &dwContentType,
- &dwFormatType,
- &hStore,
- &hMsg,
- NULL);
+ fResult = pCryptQueryObject(CERT_QUERY_OBJECT_FILE,
+ wfilename,
+ CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
+ CERT_QUERY_FORMAT_FLAG_BINARY,
+ 0,
+ &dwEncoding,
+ &dwContentType,
+ &dwFormatType,
+ &hStore,
+ &hMsg,
+ NULL);
if (!fResult) {
afsi_log("CryptQueryObject failed for [%s] with error 0x%x",
goto __exit;
}
- fResult = CryptMsgGetParam(hMsg,
- CMSG_SIGNER_INFO_PARAM,
- 0,
- NULL,
- &dwSignerInfo);
+ fResult = pCryptMsgGetParam(hMsg,
+ CMSG_SIGNER_INFO_PARAM,
+ 0,
+ NULL,
+ &dwSignerInfo);
if (!fResult) {
afsi_log("CryptMsgGetParam failed for [%s] with error 0x%x",
pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo);
- fResult = CryptMsgGetParam(hMsg,
- CMSG_SIGNER_INFO_PARAM,
- 0,
- (PVOID)pSignerInfo,
- &dwSignerInfo);
+ fResult = pCryptMsgGetParam(hMsg,
+ CMSG_SIGNER_INFO_PARAM,
+ 0,
+ (PVOID)pSignerInfo,
+ &dwSignerInfo);
if (!fResult) {
afsi_log("CryptMsgGetParam failed for [%s] with error 0x%x",
CertInfo.Issuer = pSignerInfo->Issuer;
CertInfo.SerialNumber = pSignerInfo->SerialNumber;
- pCertContext = CertFindCertificateInStore(hStore,
+ pCertContext = pCertFindCertificateInStore(hStore,
ENCODING,
0,
CERT_FIND_SUBJECT_CERT,
CertFreeCertificateContext(pCertContext);*/
if (hStore)
- CertCloseStore(hStore,0);
+ pCertCloseStore(hStore,0);
if (hMsg)
- CryptMsgClose(hMsg);
+ pCryptMsgClose(hMsg);
return pCertContext;
}
GUID subject = WIN_TRUST_SUBJTYPE_PE_IMAGE;
wchar_t wfilename[260];
LONG ret;
+ BOOL success = FALSE;
+
+ LONG (WINAPI *pWinVerifyTrust)(HWND hWnd, GUID* pgActionID, WINTRUST_DATA* pWinTrustData) = NULL;
+ HINSTANCE hWinTrust;
if (filename == NULL )
return FALSE;
+ hWinTrust = LoadLibrary("wintrust");
+ if ( !hWinTrust )
+ return FALSE;
+
+ if (((FARPROC) pWinVerifyTrust =
+ GetProcAddress( hWinTrust, "WinVerifyTrust" )) == NULL )
+ {
+ FreeLibrary(hWinTrust);
+ return FALSE;
+ }
+
mbstowcs(wfilename, filename, 260);
fSubjectFile.hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
- 0, NULL);
+ 0, NULL);
fSubjectFile.lpPath = wfilename;
fContextWSubject.hClientToken = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, GetCurrentProcessId());
fContextWSubject.SubjectType = &subject;
fContextWSubject.Subject = &fSubjectFile;
- ret = WinVerifyTrust(INVALID_HANDLE_VALUE, &trustAction, &fContextWSubject);
+ ret = pWinVerifyTrust(INVALID_HANDLE_VALUE, &trustAction, (WINTRUST_DATA *)&fContextWSubject);
if ( fSubjectFile.hFile != INVALID_HANDLE_VALUE )
CloseHandle( fSubjectFile.hFile );
CloseHandle( fContextWSubject.hClientToken );
if (ret == ERROR_SUCCESS) {
- return TRUE;
+ success = TRUE;
} else {
DWORD gle = GetLastError();
switch (gle) {
case TRUST_E_SUBJECT_NOT_TRUSTED:
afsi_log("VerifyTrust failed: File is not trusted");
break;
+ case TRUST_E_BAD_DIGEST:
+ afsi_log("VerifyTrust failed: Executable has been modified");
+ break;
case CRYPT_E_SECURITY_SETTINGS:
afsi_log("VerifyTrust failed: local security options prevent verification");
break;
default:
afsi_log("VerifyTrust failed: 0x%X", GetLastError());
}
- return FALSE;
+ success = FALSE;
}
+ FreeLibrary(hWinTrust);
+ return success;
}
void LogCertCtx(PCCERT_CONTEXT pCtx) {
DWORD dwData;
LPTSTR szName = NULL;
+ if ( hCrypt32 == NULL )
+ return;
+
// Get Issuer name size.
- if (!(dwData = CertGetNameString(pCtx,
- CERT_NAME_SIMPLE_DISPLAY_TYPE,
- CERT_NAME_ISSUER_FLAG,
- NULL,
- NULL,
- 0))) {
+ if (!(dwData = pCertGetNameString(pCtx,
+ CERT_NAME_SIMPLE_DISPLAY_TYPE,
+ CERT_NAME_ISSUER_FLAG,
+ NULL,
+ NULL,
+ 0))) {
afsi_log("CertGetNameString failed: 0x%x", GetLastError());
goto __exit;
}
szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR));
// Get Issuer name.
- if (!(CertGetNameString(pCtx,
- CERT_NAME_SIMPLE_DISPLAY_TYPE,
- CERT_NAME_ISSUER_FLAG,
- NULL,
- szName,
- dwData))) {
+ if (!(pCertGetNameString(pCtx,
+ CERT_NAME_SIMPLE_DISPLAY_TYPE,
+ CERT_NAME_ISSUER_FLAG,
+ NULL,
+ szName,
+ dwData))) {
afsi_log("CertGetNameString failed: 0x%x", GetLastError());
goto __exit;
}
szName = NULL;
// Get Subject name size.
- if (!(dwData = CertGetNameString(pCtx,
- CERT_NAME_SIMPLE_DISPLAY_TYPE,
- 0,
- NULL,
- NULL,
- 0))) {
+ if (!(dwData = pCertGetNameString(pCtx,
+ CERT_NAME_SIMPLE_DISPLAY_TYPE,
+ 0,
+ NULL,
+ NULL,
+ 0))) {
afsi_log("CertGetNameString failed: 0x%x", GetLastError());
goto __exit;
}
szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR));
// Get subject name.
- if (!(CertGetNameString(pCtx,
- CERT_NAME_SIMPLE_DISPLAY_TYPE,
- 0,
- NULL,
- szName,
- dwData))) {
+ if (!(pCertGetNameString(pCtx,
+ CERT_NAME_SIMPLE_DISPLAY_TYPE,
+ 0,
+ NULL,
+ szName,
+ dwData))) {
afsi_log("CertGetNameString failed: 0x%x", GetLastError());
goto __exit;
}
unsigned int i;
BOOL success = TRUE;
PCCERT_CONTEXT pCtxService = NULL;
+ HINSTANCE hPSAPI;
+ DWORD (WINAPI *pGetModuleFileNameExA)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize);
+ BOOL (WINAPI *pEnumProcessModules)(HANDLE hProcess, HMODULE* lphModule, DWORD cb, LPDWORD lpcbNeeded);
+ DWORD dummyLen, code;
+ DWORD cacheSize = CM_CONFIGDEFAULT_CACHESIZE;
+ DWORD verifyServiceSig = TRUE;
+ HKEY parmKey;
+
+ hPSAPI = LoadLibrary("psapi");
+
+ if ( hPSAPI == NULL )
+ return FALSE;
if (!GetModuleFileName(NULL, filename, sizeof(filename)))
return FALSE;
afsi_log("%s version %s", filename, afsdVersion);
- trustVerified = VerifyTrust(filename);
+ if (((FARPROC) pGetModuleFileNameExA =
+ GetProcAddress( hPSAPI, "GetModuleFileNameExA" )) == NULL ||
+ ((FARPROC) pEnumProcessModules =
+ GetProcAddress( hPSAPI, "EnumProcessModules" )) == NULL)
+ {
+ FreeLibrary(hPSAPI);
+ return FALSE;
+ }
+
+
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ AFSREG_CLT_SVC_PARAM_SUBKEY,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ dummyLen = sizeof(cacheSize);
+ code = RegQueryValueEx(parmKey, "CacheSize", NULL, NULL,
+ (BYTE *) &cacheSize, &dummyLen);
+ RegCloseKey (parmKey);
+ }
+
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ dummyLen = sizeof(verifyServiceSig);
+ code = RegQueryValueEx(parmKey, "VerifyServiceSignature", NULL, NULL,
+ (BYTE *) &verifyServiceSig, &dummyLen);
+ RegCloseKey (parmKey);
+ }
+
+ if (verifyServiceSig && cacheSize < 716800) {
+ trustVerified = VerifyTrust(filename);
+ } else {
+ afsi_log("Signature Verification disabled");
+ }
if (trustVerified) {
+ LoadCrypt32();
+
// get a certificate context for the signer of afsd_service.
pCtxService = GetCertCtx(filename);
if (pCtxService)
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, GetCurrentProcessId());
- if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
+ if (pEnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
afsi_log("Num of Process Modules: %d", (cbNeeded / sizeof(HMODULE)));
char szModName[2048];
// Get the full path to the module's file.
- if (GetModuleFileNameEx(hProcess, hMods[i], szModName, sizeof(szModName)))
+ if (pGetModuleFileNameExA(hProcess, hMods[i], szModName, sizeof(szModName)))
{
lstrcpy(checkName, szModName);
strlwr(checkName);
else if (pCtxService) {
PCCERT_CONTEXT pCtx = GetCertCtx(szModName);
- if (!pCtx || !CertCompareCertificate(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ if (!pCtx || !pCertCompareCertificate(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
pCtxService->pCertInfo,
pCtx->pCertInfo)) {
afsi_log("Certificate mismatch: %s", szModName);
}
if (pCtx)
- CertFreeCertificateContext(pCtx);
+ pCertFreeCertificateContext(pCtx);
}
}
}
}
}
- if (pCtxService)
- CertFreeCertificateContext(pCtxService);
+ if (pCtxService) {
+ pCertFreeCertificateContext(pCtxService);
+ UnloadCrypt32();
+ }
+
+ FreeLibrary(hPSAPI);
CloseHandle(hProcess);
return success;
}
-typedef BOOL ( APIENTRY * AfsdInitHook )(void);
-#define AFSD_INIT_HOOK "AfsdInitHook"
-#define AFSD_HOOK_DLL "afsdhook.dll"
-
/*
control serviceex exists only on 2000/xp. These functions will be loaded dynamically.
*/
RegisterServiceCtrlHandlerExFunc pRegisterServiceCtrlHandlerEx = NULL;
RegisterServiceCtrlHandlerFunc pRegisterServiceCtrlHandler = NULL;
-void afsd_Main(DWORD argc, LPTSTR *argv)
+VOID WINAPI
+afsd_Main(DWORD argc, LPTSTR *argv)
{
long code;
char *reason;
#ifdef JUMP
int jmpret;
#endif /* JUMP */
- HANDLE hInitHookDll;
- HANDLE hAdvApi32;
- AfsdInitHook initHook;
+ 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();
ServiceStatus.dwCheckPoint = 1;
ServiceStatus.dwWaitHint = 30000;
/* accept Power Events */
- ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_POWEREVENT;
+ 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 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
{
int bpower = TRUE;
/* see if we should handle power notifications */
- code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, KEY_QUERY_VALUE, &hkParm);
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
+ 0, KEY_QUERY_VALUE, &hkParm);
if (code == ERROR_SUCCESS) {
dummyLen = sizeof(bpower);
code = RegQueryValueEx(hkParm, "FlushOnHibernate", NULL, NULL,
ServiceStatus.dwWaitHint = 0;
ServiceStatus.dwControlsAccepted = 0;
SetServiceStatus(StatusHandle, &ServiceStatus);
-
+
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_SERVICE_INCORRECT_VERSIONS);
+
/* exit if initialization failed */
return;
}
/* allow an exit to be called prior to any initialization */
- hInitHookDll = LoadLibrary(AFSD_HOOK_DLL);
- if (hInitHookDll)
+ hHookDll = LoadLibrary(AFSD_HOOK_DLL);
+ if (hHookDll)
{
- BOOL hookRc = FALSE;
- initHook = ( AfsdInitHook ) GetProcAddress(hInitHookDll, AFSD_INIT_HOOK);
+ BOOL hookRc = TRUE;
+ AfsdInitHook initHook = ( AfsdInitHook ) GetProcAddress(hHookDll, AFSD_INIT_HOOK);
if (initHook)
{
hookRc = initHook();
}
- FreeLibrary(hInitHookDll);
- hInitHookDll = NULL;
+ FreeLibrary(hHookDll);
+ hHookDll = NULL;
if (hookRc == FALSE)
{
ServiceStatus.dwCheckPoint = 2;
ServiceStatus.dwWaitHint = 20000;
/* accept Power Events */
- ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_POWEREVENT;
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_PARAMCHANGE;
SetServiceStatus(StatusHandle, &ServiceStatus);
}
}
+ /* Perform Volume Status Notification Initialization */
+ cm_VolStatus_Initialization();
+
#ifdef JUMP
MainThreadId = GetCurrentThreadId();
jmpret = setjmp(notifier_jmp);
osi_panic(reason, __FILE__, __LINE__);
}
+ /* allow an exit to be called post rx initialization */
+ hHookDll = LoadLibrary(AFSD_HOOK_DLL);
+ if (hHookDll)
+ {
+ BOOL hookRc = TRUE;
+ AfsdRxStartedHook rxStartedHook = ( AfsdRxStartedHook ) GetProcAddress(hHookDll, AFSD_RX_STARTED_HOOK);
+ if (rxStartedHook)
+ {
+ hookRc = rxStartedHook();
+ }
+ FreeLibrary(hHookDll);
+ hHookDll = NULL;
+
+ if (hookRc == FALSE)
+ {
+ ServiceStatus.dwCurrentState = SERVICE_STOPPED;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 0;
+ ServiceStatus.dwWaitHint = 0;
+ ServiceStatus.dwControlsAccepted = 0;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+
+ /* exit if initialization failed */
+ return;
+ }
+ }
+
#ifndef NOTSERVICE
ServiceStatus.dwCheckPoint++;
ServiceStatus.dwWaitHint -= 5000;
SetServiceStatus(StatusHandle, &ServiceStatus);
#endif
+
+/* the following ifdef chooses the mode of operation for the service. to enable
+ * a runtime flag (instead of compile-time), pioctl() would need to dynamically
+ * determine the mode, in order to use the correct ioctl special-file path. */
+#ifndef AFSIFS
code = afsd_InitSMB(&reason, MessageBox);
if (code != 0) {
afsi_log("afsd_InitSMB failed: %s (code = %d)", reason, code);
osi_panic(reason, __FILE__, __LINE__);
}
+#else
+ code = ifs_Init(&reason);
+ if (code != 0) {
+ afsi_log("ifs_Init failed: %s (code = %d)", reason, code);
+ osi_panic(reason, __FILE__, __LINE__);
+ }
+ for (cnt = 0; cnt < WORKER_THREADS; cnt++)
+ hAFSDWorkerThread[cnt] = CreateThread(NULL, 0, ifs_MainLoop, 0, 0, NULL);
+#endif
+
+ /* allow an exit to be called post smb initialization */
+ hHookDll = LoadLibrary(AFSD_HOOK_DLL);
+ if (hHookDll)
+ {
+ BOOL hookRc = TRUE;
+ AfsdSmbStartedHook smbStartedHook = ( AfsdSmbStartedHook ) GetProcAddress(hHookDll, AFSD_SMB_STARTED_HOOK);
+ if (smbStartedHook)
+ {
+ hookRc = smbStartedHook();
+ }
+ FreeLibrary(hHookDll);
+ hHookDll = NULL;
+
+ if (hookRc == FALSE)
+ {
+ ServiceStatus.dwCurrentState = SERVICE_STOPPED;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 0;
+ ServiceStatus.dwWaitHint = 0;
+ ServiceStatus.dwControlsAccepted = 0;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+
+ /* exit if initialization failed */
+ return;
+ }
+ }
MountGlobalDrives();
ServiceStatus.dwWaitHint = 0;
/* accept Power events */
- ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_POWEREVENT;
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_PARAMCHANGE;
SetServiceStatus(StatusHandle, &ServiceStatus);
#endif
+
+ 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)
+ {
+ BOOL hookRc = TRUE;
+ AfsdStartedHook startedHook = ( AfsdStartedHook ) GetProcAddress(hHookDll, AFSD_STARTED_HOOK);
+ if (startedHook)
+ {
+ hookRc = startedHook();
+ }
+ FreeLibrary(hHookDll);
+ hHookDll = NULL;
+
+ if (hookRc == FALSE)
{
- 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);
+ ServiceStatus.dwCurrentState = SERVICE_STOPPED;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 0;
+ ServiceStatus.dwWaitHint = 0;
+ ServiceStatus.dwControlsAccepted = 0;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+
+ /* exit if initialization failed */
+ return;
}
}
+#ifndef AFSIFS
WaitForSingleObject(WaitToTerminate, INFINITE);
+#else
+ WaitForMultipleObjects(WORKER_THREADS, hAFSDWorkerThread, TRUE, INFINITE);
+ for (cnt = 0; cnt < WORKER_THREADS; cnt++)
+ CloseHandle(hAFSDWorkerThread[cnt]);
+#endif
+
+ 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);
+ if (hHookDll)
+ {
+ BOOL hookRc = TRUE;
+ AfsdStoppingHook stoppingHook = ( AfsdStoppingHook ) GetProcAddress(hHookDll, AFSD_STOPPING_HOOK);
+ if (stoppingHook)
+ {
+ hookRc = stoppingHook();
+ }
+ FreeLibrary(hHookDll);
+ hHookDll = NULL;
+
+ if (hookRc == FALSE)
+ {
+ ServiceStatus.dwCurrentState = SERVICE_STOPPED;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 0;
+ ServiceStatus.dwWaitHint = 0;
+ ServiceStatus.dwControlsAccepted = 0;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+
+ /* exit if initialization failed */
+ return;
+ }
}
+
+#ifdef AFS_FREELANCE_CLIENT
+ cm_FreelanceShutdown();
+ afsi_log("Freelance Shutdown complete");
+#endif
+
DismountGlobalDrives();
- smb_Shutdown();
+ afsi_log("Global Drives dismounted");
+
+ cm_DaemonShutdown();
+ afsi_log("Daemon shutdown complete");
+
+ afsd_ShutdownCM();
+
+ buf_Shutdown();
+ afsi_log("Buffer shutdown complete");
+
+ rx_Finalize();
+ afsi_log("rx finalization complete");
+
+#ifndef AFSIFS
+ smb_Shutdown();
+ afsi_log("smb shutdown complete");
+#endif
+
+ RpcShutdown();
+
+ cm_ReleaseAllLocks();
+
rx_Finalize();
+ afsi_log("rx finalization complete");
+
+ cm_ShutdownMappedMemory();
#ifdef REGISTER_POWER_NOTIFICATIONS
/* terminate thread used to flush cache */
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)
+ {
+ BOOL hookRc = TRUE;
+ AfsdStoppedHook stoppedHook = ( AfsdStoppedHook ) GetProcAddress(hHookDll, AFSD_STOPPED_HOOK);
+ if (stoppedHook)
+ {
+ hookRc = stoppedHook();
+ }
+ FreeLibrary(hHookDll);
+ hHookDll = NULL;
+ }
+
/* Remove the ExceptionFilter */
SetUnhandledExceptionFilter(NULL);
return(0);
}
+void usage(void)
+{
+ fprintf(stderr, "afsd_service.exe [--validate-cache <cache-path>]");
+}
+
int
-main(void)
+main(int argc, char * argv[])
{
static SERVICE_TABLE_ENTRY dispatchTable[] = {
{AFS_DAEMON_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) afsd_Main},
{NULL, NULL}
};
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (!stricmp(argv[i],"--validate-cache")) {
+ if (++i != argc - 1) {
+ usage();
+ return(1);
+ }
+
+ return cm_ValidateMappedMemory(argv[i]);
+ } else {
+ usage();
+ return(1);
+ }
+ }
if (!StartServiceCtrlDispatcher(dispatchTable))
{
printf("Hit <Enter> to terminate OpenAFS Client Service\n");
getchar();
SetEvent(WaitToTerminate);
+#ifdef AFSIFS
+ dc_release_hooks();
+#endif
}
}